Group-agnostic previous-focussed-window memory in StumpWM
I’ve started using StumpWM’s groups (like “workspaces” in other window managers) more extensively, but this broke a behaviour I like: the ability to easily switch back to the last focussed window, because StumpWM’s “last focussed” is group-specific. So I wasn’t easily about to switch quickly back and forth between two windows that were inb different groups, which turns out to be something I frequently want to do (e.g. switch back and forth between an emacsclient frame in my “emacs” group and a Firefox instance in my “web” group).
Here’s my fix [updated with some fixes on
]:;; Global 'last focussed window'
(setf *global-ante-earlier-focussed-window* 'nil)
(setf *global-earlier-focussed-window* 'nil)
(setf *global-prev-focussed-window* 'nil)
(setf *global-cur-focussed-window* 'nil)
(defun panrecord-of-last-focussed-window (currwin lastwin)
"Record last visited windows and their group."
(unless (or (search "*EQUAKE*[" (window-name currwin)) ;; don't record Equake
(equal (cons (current-window) (current-group)) *global-cur-focussed-window*))
(when (find-window-globally
(car *global-earlier-focussed-window*) (screen-groups (current-screen)))
(setf *global-ante-earlier-focussed-window* *global-earlier-focussed-window*))
(when (find-window-globally
(car *global-prev-focussed-window*) (screen-groups (current-screen)))
(setf *global-earlier-focussed-window* *global-prev-focussed-window*))
(when (find-window-globally
(car *global-cur-focussed-window*) (screen-groups (current-screen)))
(setf *global-prev-focussed-window* *global-cur-focussed-window*))
(setf *global-cur-focussed-window* (cons currwin (current-group)))))
(defun find-window-globally (window group-list)
"Check for presence of window in all groups."
(if (equal (car group-list) 'nil)
'nil
(if (member window (group-windows (car group-list)))
window
(find-window-globally window (cdr group-list)))))
(defcommand switch-to-last-focussed-window () ()
"Switch to last focussed window, irrespective of which group it is in and what group we're currently in."
(progn
(if
(and
(not (equal *global-cur-focussed-window* *global-prev-focussed-window*))
(or
;; we're in the same group [same logic below]
(equal (car (screen-groups (current-screen)))
(cdr *global-prev-focussed-window*))
;; or we can switch to the previous group
*global-prev-focussed-window*))
(progn
(switch-to-group (cdr *global-prev-focussed-window*))
(focus-window (car *global-prev-focussed-window*) t))
(if
(and
(not (equal *global-cur-focussed-window* *global-earlier-focussed-window*))
(or
(equal (car (screen-groups (current-screen)))
(cdr *global-earlier-focussed-window*))
*global-earlier-focussed-window*))
(progn
(switch-to-group (cdr *global-earlier-focussed-window*))
(focus-window (car *global-earlier-focussed-window*) t))
(if
(and
(not (equal *global-cur-focussed-window* *global-ante-earlier-focussed-window*))
(or
(equal (car (screen-groups (current-screen)))
(cdr *global-ante-earlier-focussed-window*))
*global-ante-earlier-focussed-window*))
(progn
(switch-to-group (cdr *global-ante-earlier-focussed-window*))
(focus-window (car *global-ante-earlier-focussed-window*) t))
(message "No window to switch to."))))))
(add-hook *focus-window-hook* 'panrecord-of-last-focussed-window)
;; my binding; set as you will
(define-key *root-map* (kbd "s-f") "switch-to-last-focussed-window")
The unless
statement in panrecord-of-last-focussed-window
prevents
my drop-down terminal Equake “window” from “counting” for history
tracking purposes.
The switch-to-last-focussed-window
function essentially just switches
to the last focussed window, after making sure it still exists. (If
not, switch to the window which was focussed before that one, or the
one before that one, or else don’t switch and display message
indicating this to the user.)
The last line, (define-key *root-map* (kbd "s-f") "switch-to-last-focussed-window")
, means that I can double tap s-f
(since my StumpWM prefix key is set to s-f
with (set-prefix-key (kbd "s-f"))
) to switch to the last focussed window, no matter which group
it belongs to.
I continue to really enjoy the power that StumpWM’s Common Lisp underpinnings provides the user!