# Copyright (c) 1993 by Sanjay Ghemawat
#############################################################################
# Focus Operations
#
#	Each toplevel window has a list of descendants interested in
#	the focus.  As the mouse enters a toplevel window, the focus is
#	granted to the last element in the list for that toplevel window.
#
#	focus_dest		Array maps from toplevel to list
#	focus_top		Toplevel with current focus

set focus_top ""
catch {unset focus_destination}

proc focus_restrict {toplevel} {
    global focus_top focus_dest

    if {$focus_top == $toplevel} return
    set focus_top $toplevel
    focus_recompute
}

proc focus_unrestrict {toplevel} {
    global focus_top

    if {$focus_top == $toplevel} {
	set focus_top ""
	focus_recompute
    }
}

proc focus_interest {window} {
    global focus_top focus_dest
    set toplevel [winfo toplevel $window]

    # Construct list for this toplevel if necessary
    if [catch {set list $focus_dest($toplevel)}] {
	set list ""
    }

    lremove list $window
    lappend list $window
    set focus_dest($toplevel) $list
    focus_recompute
}

proc focus_disinterest {window} {
    global focus_top focus_dest
    set toplevel [winfo toplevel $window]

    if [catch {set list $focus_dest($toplevel)}] {
	# Empty interest list?
	return
    }

    lremove list $window
    set focus_dest($toplevel) $list
    focus_recompute
}

proc focus_recompute {} {
    global focus_top focus_dest

    if {$focus_top == ""} {
	focus none
	return
    }

    set length [llength $focus_dest($focus_top)]
    if {$length < 1} {
	focus none
	return
    }

    focus [lindex $focus_dest($focus_top) [expr $length-1]]
}
