stumpwm-devel
[Top][All Lists]
Advanced

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

Re: Spatial organization of windows in StumpWM


From: Tim Cross
Subject: Re: Spatial organization of windows in StumpWM
Date: Tue, 08 Mar 2022 15:23:21 +1100
User-agent: mu4e 1.7.9; emacs 28.0.91

Hi Russell,

this is very nice. I have something a little similar, but without the
ability to add 'desktops' dynamically. The idea to think of it as a 3d
coordinate system is excellent and I intend to steal your code!

I agree with you that once you have this working you don't tend to split
windows, but instead move between them within a desktop. Splitting
windows has never worked well for me as I have very poor sight and need
a much larger font than most. Splitting always ended up with too little
displayed (either too much wrapping/truncating or too few lines). Having
virtual desktop where you can move around windows is fast and convenient
and having each desktop remember the window layout makes it easy to move
between projects, but with a standard/common window layout.

It never ceases to amaze me how just having one inspiring idea can
create such an elegant solution. In this case, the use of the 3d
coordinates is brilliant. Now that you have shown it, it seems like such
an obvious solution, yet it simply didn't occur to me! I had thought
about how I could make my own setup support dynamic creation of
desktops, but it always seemed to be more clunky than I liked.

Now I have the key and am off to hack my config....

thanks,

Tim


Russell Adams <RLAdams@adamsinfoserv.com> writes:

> 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]