stumpwm-devel
[Top][All Lists]
Advanced

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

Sv: Spatial organization of windows in StumpWM


From: Shostek
Subject: Sv: Spatial organization of windows in StumpWM
Date: Mon, 7 Mar 2022 21:00:37 +0000 (UTC)

This is phenomenal! I didn't grok it when you explained on irc but the video 
demo made perfect sense. I think this would make an very powerful contribution 
to StumpWM, if not in the core than as a module. The video is also really well 
put together, and demonstrates the true power of stump. If you feel like it, I 
think it would be quite publishable. If you'd like feedback or constructive 
criticism I would be happy to give it when I have some time.

Now please excuse me while I add all of this code to my stumpwmrc while waiting 
for it to be formally published :).

7. mar. 2022 20:12:03 Russell Adams <RLAdams@adamsinfoserv.com>:

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