1
;; window-order.jl -- keep track of recently accessed windows
2
;; $Id: window-order.jl,v 1.20 2001/02/08 04:23:15 jsh Exp $
4
;; Copyright (C) 1999 John Harper <john@dcs.warwick.ac.uk>
6
;; This file is part of sawmill.
8
;; sawmill is free software; you can redistribute it and/or modify it
9
;; under the terms of the GNU General Public License as published by
10
;; the Free Software Foundation; either version 2, or (at your option)
13
;; sawmill is distributed in the hope that it will be useful, but
14
;; WITHOUT ANY WARRANTY; without even the implied warranty of
15
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
;; GNU General Public License for more details.
18
;; You should have received a copy of the GNU General Public License
19
;; along with sawmill; see the file COPYING. If not, write to
20
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22
(define-structure sawfish.wm.util.window-order
27
window-order-most-recent
28
window-order-focus-most-recent)
33
sawfish.wm.session.init
37
(define-structure-alias window-order sawfish.wm.util.window-order)
39
;; window order high-water-mark
40
(define window-order-highest 1)
42
;; return windows in MRU order
43
(define (window-order #!optional workspace allow-iconified all-viewports)
44
(let ((windows (managed-windows)))
45
(setq windows (delete-if (lambda (w)
46
(or (not (window-mapped-p w))
47
(window-get w 'ignored)
48
(and (not allow-iconified)
49
(window-get w 'iconified))
51
(not (window-appears-in-workspace-p
55
(setq windows (delete-if window-outside-viewport-p windows)))
56
(sort windows (lambda (x y)
57
(setq x (window-get x 'order))
58
(setq y (window-get y 'order))
64
;; push window W onto the top of the cycle stack
65
(define (window-order-push w)
66
(window-put w 'order window-order-highest)
67
(setq window-order-highest (1+ window-order-highest))
68
(when (> window-order-highest 1000000) ;arbitrary big number
69
(window-order-compress)))
71
;; remove window W from the order stack
72
(define (window-order-pop w)
73
(window-put w 'order nil))
75
;; compress the order stack
76
(define (window-order-compress)
77
(let ((order (nreverse (window-order nil t t))) ;all windows
79
(map-windows (lambda (w)
80
(window-put w 'order nil)))
82
(window-put w 'order i)
83
(setq i (1+ i))) order)
84
(setq window-order-highest i)))
86
(define (window-order-most-recent #!key (windows 0))
87
"Return the most-recently focused window in the current workspace. If the
88
WINDOWS argument is given it should be a list of windows, in this case the
89
function will restrict its search to the elements of this list."
90
(let loop ((rest (window-order current-workspace nil)))
91
(cond ((null rest) nil)
92
((or (window-get (car rest) 'never-focus)
93
(and (listp windows) (not (memq (car rest) windows))))
97
(define (window-order-focus-most-recent)
98
(set-input-focus (window-order-most-recent)))
100
(define (on-viewport-change)
101
;; The problem is that any sticky windows that have been focused once
102
;; will _always_ rise to the top of the order when switching viewports
103
;; (since the topmost window is _always_ focused when entering a new
104
;; workspace). The hacky solution is to remove the order of any sticky
106
(let ((order (window-order current-workspace)))
108
(when (window-get w 'sticky-viewport)
109
(window-put w 'order nil))) order))
110
(when (eq focus-mode 'click)
111
(window-order-focus-most-recent)))
113
(sm-add-saved-properties 'order)
114
(add-swapped-properties 'order)
116
(add-hook 'sm-after-restore-hook window-order-compress)
117
(add-hook 'iconify-window-hook window-order-pop)
118
(add-hook 'viewport-moved-hook on-viewport-change))