home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.freefriends.org
/
ftp.freefriends.org.tar
/
ftp.freefriends.org
/
arnold
/
Source
/
gwm-dist.tar.gz
/
gwm-dist.tar
/
home-gwm
/
focus.gwm
< prev
next >
Wrap
Text File
|
1993-07-07
|
7KB
|
204 lines
; focus.gwm - maintain a list of focus windows and make sure that if
; there are any mapped windows that can have the focus, one always
; does.
; BUG FIX: don't give focus to root-window -- it bad! use (set-focus nil)
; instead
(if (not (boundp 'tty-window-classes))
(: tty-window-classes '("XTerm")))
(for var '(focus-list must-assign-focus current-focus-window)
(if (not (= screen. (namespace-of var)))
(defname var screen.))
(if (not (boundp var))
(set var nil)))
(: root-behavior
(state-make
root-behavior
(on focus-out (revert-focus))))
(: window-behavior
(state-make
window-behavior
(on map-notify (handle-map-notify))))
(reparse-standard-behaviors)
(de pick-focus-window (startup)
(with (fw nil)
(for w (list-of-windows 'mapped 'window)
(if (and (not fw)
(with (window w)
(member window-client-class tty-window-classes)))
(: fw w)))
(if (not fw)
(progn
(if startup
(progn
(? "WARNING: can't pick a focus window sensibly\n")
(? "WARNING: assigning focus to root window\n")
))
(: fw nil)
(: must-assign-focus t))
(if (not startup)
(progn
(? "WARNING: had to pick a focus window\n")
(bell 100))))
fw))
(if (not (boundp 'primitive-set-focus))
(: primitive-set-focus set-focus))
(df set-focus w
(with (ww window)
(tag my-set-focus-tag
(if w
(if (> (length w) 1)
(progn
(? "ERROR: set-focus takes 0 or 1 argument:\n")
(? (+ '(set-focus) w) "\n")
(exit my-set-focus-tag nil))
(if (error-occurred (: ww (eval (# 0 w))))
(progn
(? "ERROR: error in evaluation of argument:\n")
(? (+ '(set-focus) w) "\n")
(exit my-set-focus-tag nil)))))
; At this point, we have set ww to the target window, which may
; have defaulted if the argument was missing, or may be nil if
; someone is trying explicitly to set the focus to PointerRoot
; mode. We don't allow that.
; (if (null ww)
; (progn
; (? "ERROR: not allowed to set-focus to nil:\n")
; (? (+ '(set-focus) w) "\n")
; (exit my-set-focus-tag nil)))
; Make sure the window really does take the focus before
; updating focus-list. Don't add ww to focus-list if it
; is nil. Then, return the right value.
(if (primitive-set-focus ww)
(progn
(: current-focus-window ww)
(if ww
(progn
(if t ; (= check-input-focus-flag 0)
(add-to-focus-list ww))
(: must-assign-focus nil)))
t)
nil))))
(de add-to-focus-list (w)
(with (pos (member w focus-list))
(: focus-list
(if (null pos) ; This one has never had the focus.
(+ (list w) focus-list)
(+ (list w)
(sublist 0 pos focus-list)
(sublist (+ pos 1) (length focus-list) focus-list))))))
; let's see if the autofocus can do this for us
;(: to-be-done-after-setup
; (+ to-be-done-after-setup
; '((set-focus (pick-focus-window t))))) ; Initial focus must be somewhere
; This function is one of the main points of our focus handling. Called
; by a focus-in event in the root window, it assigns the focus to the
; window that most recently had it, on the assumption that the one that
; just gave it up was destroyed or unmapped somehow, perhaps by being
; iconified or its client exiting. Warn the user if things look funny.
(de revert-focus ()
(with (w (# 0 focus-list) pos nil)
(if (member w (list-of-windows))
; So the window still exists. But is it mapped?
(with (window w)
(if window-is-mapped
(progn
(? "WARNING: a mapped window relinquished the focus\n")
; can't really do this because of sam? (bell 100)
))))
; One way or another the first element is coming out of the
; focus list now. We start at the second and assign the focus
; to the first one we find that is still a window and still
; mapped. Elements to the left of that are all deleted.
(for pfw (sublist 1 (length focus-list) focus-list)
(if (and (null pos)
(member pfw (list-of-windows))
(with (window pfw) window-is-mapped))
(: pos (member pfw focus-list))))
(if (null pos)
; Wow. Not one of the windows that formerly had the focus
; is in a position to take it back. What a situation! We'll
; try to pick a focus window; if we can't, the focus goes to
; the root, and the next window created or deiconified will
; get it (by virtue of the "opening" code and the global
; (per-screen) flag must-assign-focus).
(progn
(: focus-list nil)
(set-focus (pick-focus-window nil)))
; Here, things are not so bad. We've located the window that
; most recently had the focus and can take it back.
(progn
(: focus-list (sublist pos (length focus-list) focus-list))
(: current-focus-window (# 0 focus-list))
(primitive-set-focus (# 0 focus-list))
(with (window (# 0 focus-list))
(if (not window-is-mapped)
(revert-focus))))))) ; It's gone! Try again...
; We have to maintain the property list correctly if we lose the focus
; due to being iconified. This also allows us to set the focus if needed
; on de-iconification. Creation will have to be handled elsewhere...
(if (not (boundp 'primitive-iconify-window))
(: primitive-iconify-window iconify-window))
(de iconify-window nil
(if (eq window-status 'window)
(progn
(window-property (# 'has-focus window-property nil))
; Now THIS, THIS is what I call a HIDEOUS KLUDGE.
(send-user-event 'focus-out)
(primitive-iconify-window))
(eq window-status 'icon)
(progn
(primitive-iconify-window) ; Current window is now the window.
;
; The following three lines aren't really bad code, but we don't want
; them right now. If you put them in, and take out the "if t" following,
; then only some windows will get the focus on deiconify, instead of
; all of them.
; (if (and must-assign-focus
; (or (member window-client-class tty-window-classes)
; (member window focus-list)))
(if t
(if (set-focus)
(send-user-event 'focus-in))))
(primitive-iconify-window))) ; Don't know this kind, just do it.
; Automatically assign focus to a window on mapping, provided it is
; either a tty-window or else a pop-up from the window which has the focus.
(de handle-map-notify nil
(if (and (eq window-status 'window)
(eq wob-status 'window)
(or (member window-client-class tty-window-classes)
(and window-is-transient-for
(= window-is-transient-for current-focus-window))))
(currtop nil)))