;; fvwm-autoraise  -  Delayed autoraise for fvwm-windows
;; Contributed by Bruno Daniel (daniel@fzi.de)
;;
;; I've changed the function maintain-focus-in in fvwm-window.gwm in order to 
;; accomplish a real practical autoraise function:
;; 
;; - autoraise-delay can be set. This prevents flickering of all the windows 
;;   on your desktop touched by the mouse when you move the mouse over the 
;;   screen.
;; - autoraise-delay is not performed for a window that has a smaller window 
;;   above it and inside its borders.
;;   This avoids obscuring small windows, which is very likely to happen in the
;;   autoraise-function of other window managers.
;; 

;; Default value for autoraise-delay
(setq autoraise-delay 80)

;; Does window 1 contain window 2?
(defun window_contains (w1 w2)
    (with (window w1
         w1l window-x
         w1t window-y
         w1r (+ window-width w1l)
         w1b (+ window-height w1t)
         window w2
         w2l window-x
         w2t window-y
         w2r (+ window-width w2l)
         w2b (+ window-height w2t))
       (and (< w1l w2l)
          (< w1t w2t)
          (> w1b w2b)
          (> w1r w2r))))

(defun maintain-focus-in ()
  (send-user-event 'focus-in window)
  (## 'virt-col window (# 'virt-col2 window))
  (## 'virt-act window t)
  (if (boundp 'icon-mgr-focusin)
      (icon-mgr-focusin))
  (if (eval (boundp 'autoraise))
      (progn 
	(with (etime (elapsed-time)
	       x0 (+ window-x)
	       x1 (+ window-x window-width)
	       y0 (+ window-y)
	       y1 (+ window-y window-height)
	       would_obscure_other_windows ()
	       above_current_window ())
	      (for w (list-of-windows 'stacking-order 'mapped)
		   ;; Because the windows are sorted in stacking order (from
		   ;; bottom to top), we can easily determine the state
		   ;; above_current_window.
		   (if (= w window)
		       (: above_current_window t)
		     (if (and above_current_window 
			      (window_contains window w))
			 (: would_obscure_other_windows t))))
	      (if (not would_obscure_other_windows)
		  (progn
		    ;; Proceed after autoraise-delay
		    (while (< (- (elapsed-time) etime) autoraise-delay)
		      (process-events))
		    ;; Is the mouse cursor still inside the original window?
		    (if (and (< x0 (# 0 (current-mouse-position)))
			     (> x1 (# 0 (current-mouse-position)))
			     (< y0 (# 1 (current-mouse-position)))
			     (> y1 (# 1 (current-mouse-position))))
			;; If yes, raise the window.
			(raise-window))))))
    (if (and fvwm-virtual-colors
             (boundp 'virtual-update)
             (not (= (# 'virt-col1 window) (# 'virt-col2 window))))
        (virtual-update)))
  )

