tkgoodstuff/tcl/Fvwm.tcl

387 lines
10 KiB
Tcl
Executable File

#Fvwm module interface for tkgoodstuff
proc FvwmDeclare {} {
TKGDeclare Fvwm(dostyle) 1 -vartype boolean \
-typelist [list General Fvwm]\
-label "Tell Fvwm to make tkgoodstuff stay on top, etc."\
-help {You can configure Fvwm to treat tkgoodstuff specially
by not giving it a title, borders, by letting it stay
on top, not including it in the window list or circulation
list, and so on. By default, when launched by fvwm, tkgoodstuff
tells fvwm to do all of this automatically.}
}
proc FvwmDoOnLoad {} {
if [info exists Fvwm(outid)] return
#ensure tkfvwm is loaded
package require Tkfvwm
# Set up communication with fvwm
if [catch "fvwm init [lindex $argv 0] [lindex $argv 1]" e] {
TKGError "Something went wrong trying to initialize communication with fvwm:
$e" exit
}
set Fvwm(outid) [lindex $argv 0]
if $Fvwm(dostyle) {
setifunset Fvwm(Style) {
"BorderWidth 0"
CirculateSkipIcon
CirculateSkip
ClickToFocus
NoTitle
NoHandles
Sticky
WindowListSkip
StaysOnTop
RandomPlacement
}
fvwm send $Fvwm(outid) "Style \"tkgoodstuff\" [join $Fvwm(Style) ,]"
unset Fvwm(Style)
}
bind TkgButton <1> "FvwmTkgbuttonStuff %W; [bind TkgButton <1>]"
TKGAddToHook TKG_alldone_hook FvwmTKGButtonInit
FvwmStart
}
# Set up bindings for fvwm messages, and ask fvwm for all window data
proc FvwmStart {} {
global Fvwm
fvwm AddWindow {FvwmAddWindow %W %f %x %y %w %h %t}
fvwm ConfigureWindow {FvwmConfigureWindow %W %f %x %y %w %h %t}
fvwm DestroyWindow {FvwmDestroyWindow %W}
fvwm WindowName {FvwmWindowName %W %N}
fvwm IconName {FvwmIconName %W %N}
fvwm ResName {FvwmResName %W %N}
fvwm ResClass {FvwmResClass %W %N}
fvwm NewPage {FvwmNewPage %X %Y %D %x %y}
fvwm NewDesk {FvwmNewDesk %T}
fvwm Map {FvwmMap %W}
fvwm Iconify {FvwmIconify %W %x %y %w %h}
fvwm IconLocation {FvwmIconLocation %W %x %y %w %h}
fvwm Deiconify {FvwmDeiconify %W}
fvwm FocusChange {FvwmFocusChange %W}
# fvwm IconFile {FvwmIconFile %W %N}
# fvwm DefaultIcon {FvwmDefaultIcon %W %N}
# fvwm String {FvwmString %N}
# fvwm MiniIcon {FvwmMiniIcon %W %N}
TKGDoHook FvwmStartHook
fvwm send $Fvwm(outid) Send_WindowList
}
# Cancel fvwm message binding while tkgoodstuff is redrawing
proc FvwmSuspend {} {
foreach c {
AddWindow ConfigureWindow DestroyWindow WindowName IconName
ResName ResClass NewPage NewDesk Map Iconify IconLocation
Deiconify FocusChange} {
fvwm $c {}
# Iconfile DefaultIcon String MiniIcon
}
}
proc FvwmCreateWindow {} {}
# Other clients (e.g., WWW) might call this
proc TKGExec {cmd {name ""}} {
FvwmNextOrExec $cmd $name
}
# A click on a sunken button takes us to next
# window of the appropriate name.
proc FvwmTkgbuttonStuff {w} {
if [string match [$w cget -relief] sunken] {
if ![Empty [set wn [$w cget -windowname]]] {
FvwmNext $wn
}
}
}
# Restarting an fvwm module requires telling fvwm to invoke it.
proc TKGRestart {} {
global Fvwm argv argv0
fvwm send $Fvwm(outid) \
"[file tail $argv0] [lreplace $argv 0 4]"
after 500
TKGQuit
}
# If we just exit, an fvwm bug can make fvwm race if we're leaving
# children (as of fvwm2-0-43).
proc TKGReallyQuit {} {
fvwm send 0 KillMe
exit
}
proc FvwmNextOrExec {cmd {name ""}} {
global Fvwm
if ![FvwmNext [list $name]] {
if [catch "exec $cmd &" err] {
TKGError $err
}
}
}
# We locate the next window in our list whose WindowName or ResClass
# matches one of the names, and goto it.
proc FvwmNext {{names ""} {incr 1}} {
global Fvwm FvwmWL FvwmW
if [info exists Fvwm(NextLast)] {
set current $Fvwm(NextLast)
} else {
set current $FvwmW(focus)
}
set wl [lsort [array names FvwmWL]]
set i [expr ([lsearch $wl $current] + $incr) % [llength $wl]]
set wl [concat [lrange $wl $i end] $wl]
foreach w $wl {
foreach name $names {
set name [string tolower [set name]*]
foreach vartype {windowname resname resclass} {
if [string match $name \
[string tolower $FvwmW($w,$vartype)]] {
set answer 1
break
}
}
if [info exists answer] break
}
if [info exists answer] break
}
if ![info exists answer] {
return 0
}
FvwmGoto $w
return 1
}
# We go to the right desk and page, and raise. If the window has a
# style flag set for ClickToFocus (2^10) or SloppyFocus (2^11) we give
# it focus (with MouseFocus focusing warps the pointer).
proc FvwmGoto {w} {
global Fvwm FvwmW
fvwm send $w {Iconify -1}
fvwm send $w {Raise ""}
fvwm send $Fvwm(outid) "Desk 0 $FvwmW($w,t)"
fvwm send $Fvwm(outid) "GotoPage $FvwmW($w,npagex) $FvwmW($w,npagey)"
if {$FvwmW($w,flags) & 3072} {
fvwm send $w "Focus"
}
set Fvwm(NextLast) $w
}
proc FvwmPrev {{name ""}} {FvwmNext $name -1}
# Code to maintain our own window database
proc FvwmAddWindow {id flags x y w h t} {
FvwmConfigureWindow $id $flags $x $y $w $h $t
TKGDoHook Fvwm_AddWindow_hook $id
}
proc FvwmConfigureWindow {id flags x y w h t} {
global FvwmW FvwmWL
if ![info exists FvwmW($id,iconic)] {set FvwmW($id,iconic) 0}
foreach var {flags x y w h t} {
set FvwmW($id,$var) [set $var]
}
set FvwmW($id,npagex) [expr ($x+$FvwmW(pagex))/[winfo vrootwidth .]]
if {$FvwmW($id,npagex)<0} {set FvwmW($id,npagex) 0}
set FvwmW($id,npagey) [expr ($y+$FvwmW(pagey))/[winfo vrootheight .]]
if {$FvwmW($id,npagey)<0} {set FvwmW($id,npagey) 0}
set FvwmWL($id) 0
TKGDoHook Fvwm_ConfigureWindow_hook $id
}
proc FvwmWindowName {id name} {
global FvwmW
set FvwmW($id,windowname) $name
# sometimes apparently resclass and resname don't get set
# if ![info exists FvwmW($id,resclass)] {
# set FvwmW($id,resclass) dummyclass
# set FvwmW($id,resname) dummyname
# }
FvwmTKGButtonCheck $name
TKGDoHook Fvwm_WindowName_hook $id
}
proc FvwmIconName {id name} {
global FvwmW
set FvwmW($id,iconname) $name
TKGDoHook Fvwm_IconName_hook $id
}
proc FvwmResName {id name} {
global FvwmW
set FvwmW($id,resname) $name
TKGDoHook Fvwm_ResName_hook $id
}
proc FvwmResClass {id name} {
global FvwmW
set FvwmW($id,resclass) $name
FvwmTKGButtonCheck $name
TKGDoHook Fvwm_ResClass_hook $id
}
proc FvwmDestroyWindow {id} {
global FvwmWL FvwmW
catch {unset FvwmWL($id)}
FvwmTKGButtonCheck $FvwmW($id,windowname)
FvwmTKGButtonCheck $FvwmW($id,resclass)
TKGDoHook Fvwm_DestroyWindow_hook $id
foreach index [array names FvwmW] {
if [string match $id, $index] {
unset FvwmW($index)
}
}
}
# For sticky windows, we get no configure message, so we recalc page
# on NewPage.
proc FvwmNewPage {X Y D x y} {
global Fvwm FvwmW FvwmWL
set FvwmW(pagex) $X
set FvwmW(pagey) $Y
set FvwmW(npagex) [expr $FvwmW(pagex)/[winfo vrootwidth .]]
set FvwmW(npagey) [expr $FvwmW(pagey)/[winfo vrootheight .]]
set FvwmW(desktop) $D
set FvwmW(maxpagex) $x
set FvwmW(maxpagey) $y
foreach id [array names FvwmWL] {
if {$FvwmW($id,flags) & 4} {
set FvwmW($id,npagex) [expr ($FvwmW($id,x)+$X)/[winfo vrootwidth .]]
if {$FvwmW($id,npagex)<0} {set FvwmW($id,npagex) 0}
set FvwmW($id,npagey) [expr ($FvwmW($id,y)+$Y)/[winfo vrootheight .]]
if {$FvwmW($id,npagey)<0} {set FvwmW($id,npagey) 0}
set FvwmW($id,t) $D
TKGDoHook Fvwm_ConfigureWindow_hook $id
}
}
TKGDoHook Fvwm_NewPage_hook
}
proc FvwmNewDesk {T} {
global FvwmW
set FvwmW(desktop) $T
TKGDoHook Fvwm_NewDesk_hook
}
proc FvwmIconify {id x y w h} {
global FvwmW
set FvwmW($id,iconic) 1
set FvwmW($id,iconlocx) $x
set FvwmW($id,iconlocy) $y
set FvwmW($id,iconw) $w
set FvwmW($id,iconh) $h
TKGDoHook Fvwm_Iconify_hook $id
}
proc FvwmIconLocation {id x y w h} {
global FvwmW
set FvwmW($id,iconx) $x
set FvwmW($id,icony) $y
set FvwmW($id,iconw) $w
set FvwmW($id,iconh) $h
TKGDoHook Fvwm_IconLocation_hook $id
}
proc FvwmDeiconify {id} {
global FvwmW
set FvwmW($id,iconic) 0
TKGDoHook Fvwm_Deiconify_hook $id
}
proc FvwmFocusChange {id} {
global FvwmW
set FvwmW(focus) $id
TKGDoHook Fvwm_FocusChange_hook $id
}
proc FvwmMap {id} {
global FvwmW
set FvwmW($id,mapped) 1
TKGDoHook Fvwm_Map_hook $id
}
proc FvwmIconFile {id file} {
global FvwmW
set FvwmW($id,iconfile) $file
TKGDoHook Fvwm_IconFile_hook $id
}
proc FvwmMiniIcon {id file} {
REPORT id file
global FvwmW
set FvwmW($id,miniicon) $file
TKGDoHook Fvwm_MiniIcon_hook $id
}
proc FvwmDefaultIcon {id icon} {
global FvwmW
set FvwmW($id,defaulticon) $icon
TKGDoHook Fvwm_DefaultIcon_hook $id
}
# Fvwm can now send modules an arbitrary string
proc FvwmString {s} {
TKGDoHook Fvwm_String_hook $s
}
# Utilities used by TKGButtons
# Check if any windows with windowname or resclass matching pattern
proc FvwmAnyWindowsOfName {pattern} {
global FvwmWL FvwmW
set somewins 0
foreach id [array names FvwmWL] {
if {[string match $pattern $FvwmW($id,windowname)]
|| [string match $pattern $FvwmW($id,resclass)]} {
set somewins 1
break
}
}
return $somewins
}
# Check if any TKGButton is looking for a window with
# windowname or resclass of name.
proc FvwmTKGButtonCheck {name} {
global FvwmWL FvwmW Fvwm_trackbuttons
foreach pattern [array names Fvwm_trackbuttons] {
if [string match $pattern $name] {
FvwmTKGButtonTrack $pattern
}
}
}
# Set relief of all TKGButtons tracking pattern
proc FvwmTKGButtonTrack {pattern} {
global Fvwm_trackbuttons TKG
if [FvwmAnyWindowsOfName $pattern] {
set relief sunken
} else {
set relief notsunken
}
foreach buttonname $Fvwm_trackbuttons($pattern) {
upvar \#0 $buttonname-params P
if [winfo exists $P(pathname)] {
if {[string match notsunken $relief]} {
set relief $P(relief)
if {[Empty $relief]} {
set relief $TKG(butrelief)
}
}
$P(pathname) configure -relief $relief
}
}
}
# Set relief of all TKGButtons
proc FvwmTKGButtonInit {} {
foreach pattern [array names Fvwm_trackbuttons] {
FvwmTKGButtonTrack $pattern
}
}
DEBUG "We're an fvwm module. Loaded Fvwm.tcl"