#
# Section: Menus
#
# This section defines a small menu structure.  The main menu contains
# some typical entries, and uses a hook (main-menu.hook) to allow the
# user to add new entries.  Most of the default entries are submenus,
# which are also defined here.
#

#=====================================================  9. user functions
# 9. user functions
# Now define some handy complex functions
DestroyFunc page-and-warp
AddToFunc page-and-warp "I" GotoPage $0 $1
+ "I" Next [!iconic CurrentScreen CurrentDesk] Focus

DestroyFunc desk-and-warp
AddToFunc desk-and-warp "I" Desk $0 $1
+ "I" Next [!iconic CurrentScreen CurrentDesk] Focus

DestroyFunc Toggle-Page
AddToFunc Toggle-Page   "I" EdgeScroll 0 0
+                       "I" EdgeScroll 100 100

# use as Key F25      A N Popupat Window-Ops
DestroyFunc Popupat
AddToFunc Popupat "I" CursorMove -1000 -1000
+	          "I" Popup Window-Ops

#The 'None' line says only do this if no window matching $0 exists.
DestroyFunc MailFunction
AddToFunc MailFunction     "I" Next [$0] Iconify -1
+                          "I" Next [$0] focus
+                          "I" None [$0] Exec $0 $1

DestroyFunc warp-or-run
AddToFunc warp-or-run "I" Next [$0 CirculateHit] Iconify -1
+ "I" Next [$0 CirculateHit] Focus
+ "I" None [$0] $1
# Use as 


# This one moves and then raises the window if you drag the mouse,
# only raises the window if you click,  or does a RaiseLower if you double 
# click
DestroyFunc "Move-or-Raise"
AddToFunc "Move-or-Raise" "M" Move
+              "M" Raise
+              "C" Raise
+              "D" RaiseLower

AddToFunc Move-or-Raise2        M Raise
+                               M Move
+                               D Lower

AddToFunc PrintFunction         I Raise
+                               I Exec xdpr -id $w

# This one moves and then lowers the window if you drag the mouse,
# only lowers the window if you click,  or does a RaiseLower if you double 
# click
DestroyFunc "Move-or-Lower"
AddToFunc "Move-or-Lower" "M" Move
+              "M" Lower
+              "C" Lower
+              "D" RaiseLower

# This one moves or (de)iconifies:
DestroyFunc "Move-or-Iconify"
AddToFunc "Move-or-Iconify" "M" Move
+              "D" Iconify
+              "C" Iconify

# This one resizes and then raises the window if you drag the mouse,
# only raises the window if you click,  or does a RaiseLower if you double 
# click
DestroyFunc "Resize-or-Raise"
AddToFunc "Resize-or-Raise" "M" Resize
+              "M" Raise
+              "C" Raise
+              "D" RaiseLower


# This one maximizes vertically if you click (leaving room for the
# GoodStuff bar at the bottom, or does a full maximization if you
# double click, or a true full vertical  maximization if you just 
# hold the mouse button down.
DestroyFunc "max_vert_func"
AddToFunc "max_vert_func" "M" Maximize 0 100
+              "C" Maximize 0 80
+              "D" Maximize 100 100


# This one maximizes horizontally if you click, or does a full
# maximization if you double click, or a true 80% horizontal
# maximization if you just hold the mouse button down. 
DestroyFunc "max_hor_func"
AddToFunc "max_hor_func" "M" Maximize 80 0
+              "C" Maximize 100 0
+              "D" Maximize 100 100

# This one maximizes if you click, or does a full
# maximization if you double click, or a true 50%  maximization if you
# just hold the mouse button down.  
DestroyFunc "max_diag_func"
AddToFunc "max_diag_func" "M" Maximize 50 50
+              "C" Maximize 80 80
+              "D" Maximize 100 100


# The Focus command no longer raises the window automatically.
# Here is a function that emulates the old Focus behavior.
DestroyFunc focus-and-raise
AddToFunc   focus-and-raise "I" Focus
+                           "I" Raise
+			    "I" WarpToWindow 5p 5p

DestroyFunc "Goto-Mail"
AddToFunc "Goto-Mail" "I" Desk 0 0
+              "I" Warp "VM" VM

# Simulate the Warp function from older fvwm
DestroyFunc Warp
AddToFunc Warp "I" Next $1 Iconify -1
+              "I" Next $1 focus
+              "I" CursorMove 2 2

AddToFunc FocusAndWarp I Focus
+                      I WarpToWindow 2p 2p

AddToFunc DeiconifyFocusAndWarp I Iconify -1
+                               I FocusAndWarp

AddToFunc ChangeDefaultFocus I Style * $0
+                            I Recapture

#The  "CursorMove" does the  trick.   I suppose larger  values could be
#used to get you to wherever you wanted to be within the window.

AddToFunc XPMBack "I" Exec xpmroot /usr/local/share/graphics/xpm/$0
AddToFunc ImageBack "I" Exec xv -root -quit /u/ericding/Pictures/images/$0
 
# AddToFunc Rsh-Func "I" Exec rxterm $0 white:gray30 80x40 $DISPLAY "-cr
# white -title $0 -e ~rod/bin/tcsh -l" 

AddToFunc Iconify-Func  "I" Iconify
+                       "I" Raise

DestroyFunc FocusRaise
AddToFunc FocusRaise I Raise
+ I Focus
+ I Iconify off


DestroyFunc RestoreWindowGeometry
AddToFunc   RestoreWindowGeometry
Read saved-window-geometries Quiet

DestroyModuleConfig FvwmEvent-NewWindow: *
*FvwmEvent-NewWindow: add_window RestoreWindowGeometry

AddToFunc StartFunction
+ I Module FvwmEvent FvwmEvent-NewWindow
AddToFunc StartFunction I Module FvwmCommandS
AddToFunc StartFunction
+ I Module FvwmPerl

DestroyFunc SaveWindowGeometry
AddToFunc   SaveWindowGeometry
+ I AddToFunc RestoreWindowGeometry
+ I + I ThisWindow ('$0') ResizeMove $1 $2 $3 $4
+ I Exec echo "+ I ThisWindow ('$0') ResizeMove $1 $2 $3 $4" >>$[FVWM_USERDIR]/saved-window-geometries

Key F4 A CS Pick SaveWindowGeometry $[w.name] $[w.x] $[w.y] $[w.width] $[w.height]

#The plan is this, define a named button in FvwmButtons using Id:
#  *FvwmButtons: (Id deskname, Text zero)
#if you use MyGotoDesk instead of GotoDesk, the "zero" in FvwmButtons
#will be automatically replaced with the current desk name.

AddToFunc MyGotoDesk
+ I GotoDesk $*
+ I PipeRead `echo "SendToModule FvwmButtons ChangeButton deskname Text \
        '\$[desk.name$d]'"

# AddToFunc MyMove M Move
# Mouse 1                W       4       MyMove

DestroyFunc Warp-or-Run-Browser
AddToFunc Warp-or-Run-Browser
+ "I" Next ("*Phoenix") Warp-and-Raise
+ "I" TestRc (Match) Break
+ "I" Next ("Galeon") Warp-and-Raise
+ "I" TestRc (Match) Break
+ "I" Next ("Mozilla") Warp-and-Raise
+ "I" TestRc (Match) Break
+ "I" Exec //usr/bin/mozilla

#####
# Autohide console example: http://dev.gentoo.org/~taviso/screenshots/autohide_console.png
##################
DestroyFunc StartHiddenConsole
AddToFunc StartHiddenConsole
+ I Exec exec rxvt +sb -geometry 144x8+0+0 -name HiddenConsole
+ I Wait HiddenConsole
+ I Next (HiddenConsole) Resize $[vp.width]p 12
+ I Autohide HiddenConsole 250 0 N

# XXX: This doesnt change focus, should it?
# Win+H to drop the hidden console down.
DestroyFunc HiddenConsoleKeyBinding
AddToFunc HiddenConsoleKeyBinding
+ I ThisWindow (Shaded) FuncAutoEnter
+ I TestRc (NoMatch) NoWindow FuncAutoEnter


DestroyFunc SelectWindow
AddToFunc   SelectWindow
  + I Focus
  + I Raise
  + I WarpToWindow 50 50

DestroyFunc ScreenDump
AddToFunc ScreenDump
+ I schedule 0 0 exec xwd
+ I schedule <some delay> 0 ...

# switches to a window if it is not visible (or not on the current
# page) and which iconifies the window if it is on top on the current
# page (e.g. fully visible).
DestroyFunc FuncFvwmIconifyOrFocusAndRaise
AddToFunc   FuncFvwmIconifyOrFocusAndRaise
+ I ThisWindow (Iconic) Iconify off
+ I TestRc (NoMatch) ThisWindow (Raised) Iconify on
+ I ThisWindow (!Iconic) Focus
+ I ThisWindow (!Iconic) Raise

*FvwmIconMan: action  Mouse 1 A sendcommand FuncFvwmIconifyOrFocusAndRaise

DestroyFunc FullScreen
AddToFunc FullScreen
+ I ThisWindow (!Maximized) Style $n BorderWidth 0
+ I ThisWindow ( Maximized, !"bluescreen") Style $n BorderWidth 1
+ I ThisWindow Maximize
+ I ThisWindow (!Maximized) WarpToWindow -5p -5p

AddToFunc MoveAndGotoPage
+ I Raise
+ I MoveToPage $0 $1
+ I GotoPage $0 $1

#Key Right W CM4 MoveAndGotoPage +1p +0p

AddToFunc	Window-Menu-Func
+	I	ThisWindow (HasHandles) Menu Window-Menu Interior 0 0 Close
+	I	ThisWindow (!HasHandles) Menu Window-Menu-No-Handles Interior 0 0 Close

AddToFunc move_to_center
+ I Piperead "echo move $(( ($[vp.width] - $[w.width]) / 2 ))p $(( ($[vp.height] - $[w.height]) / 2 ))p"

AddToFunc MoveMozilla
+	I WindowID $0 ("*Mozilla*") PipeRead `echo MoveToPage 1 0`

DestroyFunc SmartStart 
AddToFunc SmartStart
	+ I Next ($0) Iconify off
	+ I Next ($0) Raise
	+ I Next (AcceptsFocus, $0) focus
	+ I None ($0) Exec exec $1


# Auto hide stuff
AddToFunc autohide
+ I ThisWindow ($0) Deschedule $[w.id]
+ I TestRc (!Match) Deschedule -$[w.id]
+ I ThisWindow ($0) ThisWindow (shaded) autohide_show $1 $3
+ I TestRc (!Match) All ($0, !shaded) autohide_hide $2 $3

AddToFunc autohide_show
+ I Schedule $0 -$[w.id] WindowShade $1 off
+ I Schedule $0 -$[w.id] Deschedule $[w.id]
+ I Schedule $0 -$[w.id] Deschedule -$[w.id]

AddToFunc autohide_hide
+ I Schedule $0 $[w.id] WindowShade $1 on
+ I Schedule $0 $[w.id] Deschedule $[w.id]
+ I Schedule $0 $[w.id] Deschedule -$[w.id]

AddToFunc StartFunction
+ I Module FvwmAuto FvwmAutohide -menter enter_handler

#AddToFunc enter_handler
#+ I autohide FvwmButtons 250 500 N
#            ^           ^   ^   ^
#            |           |   |   |___  Shade direction (optional)
#            |           |   |________ Hide delay
#            |           |___________  Show delay
#            |_______________________  Unique window name/resource






AddToFunc winame_event
+ I ThisWindow (XTerm) ThisWindow ("*(root@*") Style $n Colorset 1, HilightColorset 7
+ I ThisWindow (XTerm) ThisWindow ("*(srivasta@*") Style $n Colorset 3, HilightColorset 4
#*FvwmEvent: window_name winame_event

#And for the future 2.5.8+ use a more appropriate:
#  AddToFunc winame_event
#  + I ThisWindow (XTerm) ThisWindow ("*(root@*") WindowStyle Colorset ...
#  + I ThisWindow (XTerm) ThisWindow ("*(srivasta@*") WindowStyle Colorset ...


AddToFunc SetShadabilityForCertainWindows
  + I ThisWindow (Gaim) State 1
  + I ThisWindow (Miag) State 1

DestroyFunc StayOnTop-func
AddToFunc StayOnTop-func
+ I Style "$0" StaysOnTop
+ I All ("$0") RecaptureWindow

DestroyFunc wheel-goes-up
AddToFunc Wheel-goes-up
+ D WindowShade True   

DestroyFunc Wheel-goes-down
AddToFunc Wheel-goes-down
+ D WindowShade False

DestroyFunc Close-or-kill
AddToFunc Close-or-kill
+ I Raise
+ C Close
+ H Destroy
+ H Beep

##########################################################################
# Function:     Disable ALL buttons 
#               (This needs to be called when resetting between styles
#               with different numbers of buttons)
#========================================================================#
DestroyFunc     "RemoveAllButtons"
AddToFunc       "RemoveAllButtons"
+ "I"   Style "*"       NoButton 0, NoButton 1, NoButton 2, NoButton 3, \
                        NoButton 4, NoButton 5, NoButton 6, NoButton 7, \
                        NoButton 8, NoButton 9

DestroyFunc ToggleWindowTitle
AddToFunc   ToggleWindowTitle
+ I ThisWindow (State 11) WindowStyle Title
+ I TestRc (!Match) WindowStyle !Title
+ I State 11 toggle

#####
# You can browse directories and files with the fvwm-menu-directory
# script included with Fvwm, its very configurable (as you might expect!),
# and very useful.
#
# http://www.mail-archive.com/fvwm%40hpc.uh.edu/msg05260.html
#################
DestroyFunc FuncFvwmMenuDirectory
AddToFunc FuncFvwmMenuDirectory
+ I PipeRead 'case "$0" in \
        "$[fvwm_rom_path]"*)   myexec="$[fvwm_rom_exec]"    \
                               mypng=games_puzzles_dice.png;; \
        "$[fvwm_video_path]"*) myexec="$[fvwm_video_exec]" \
                               mypng=menu/video.xpm;; \
        "$[fvwm_audio_path]"*) myexec="$[fvwm_audio_exec]" \
                               mypng=menu/music.xpm;; \
        "$[fvwm_image_path]"*) myexec="$[fvwm_image_exec]" \
                               mypng=menu/viewer.xpm;; \
    esac; \
    fvwm-menu-directory --icon-title menu/folder-open.xpm \
                        --icon-app   menu/utility.xpm     \
                        --icon-file  ${mypng:-menu/item.xpm}       \
                        --icon-dir   menu/folder.xpm   \
                        --dir "$0" --xterm exec --exec-file "${myexec:-gvim}"'

#####
# `Pick` is very handy, if it's obvious which window you're talking about,
# The command is executed immediately within the context of that window.
#
# If it isnt obvious, for example, you select `Move` from the Root menu, the
# cursor becomes a crosshair, and you can select the window you you would like
# to apply the command to by clicking it.
#
# This saves a lot of work, you can use `Pick` with everything that might be
# Called without context and only write one function/menu instead of two.
#
# Note that the Center Window command subtracts (126/2) pixels to make way for my
# Panel.
#################
DestroyMenu FvwmMoveMethods
AddToMenu FvwmMoveMethods
+ "Move to Top" Pick AnimatedMove keep 0p
+ "Move to Left" Pick AnimatedMove 0p keep
+ "Move to Right" Pick PipeRead "echo AnimatedMove $$(($[vp.width] - $[w.width]))p keep"
+ "Move to Bottom" Pick PipeRead "echo AnimatedMove keep $$(($[vp.height] - $[w.height]))p"
+ "" Nop
+ %window.png%"Center Window" Pick PipeRead "echo AnimatedMove $$(((($[vp.width]-$[w.width])/2)-(126/2)))p \
    $$((($[vp.height]-$[w.height])/2))p"
+ "" Nop
+ %hardware_mouse.png%"Pack Up"%alt_sft_up.png% Pick PackWrapperUp
+ %hardware_mouse.png%"Pack Left"%alt_sft_left.png% Pick PackWrapperLeft
+ %hardware_mouse.png%"Pack right"%alt_sft_right.png% Pick PackWrapperRight
+ %hardware_mouse.png%"Pack down"%alt_sft_down.png% Pick PackWrapperDown
+ "" Nop
+ %numbers_counter.png%"Move To Page" Popup MenuPageList
+ "" Nop
+ %hardware_mouse.png%"Interactive Move" Pick Move

DestroyMenu MenuPageList
AddToMenu MenuPageList
+ "1" Pick MoveToPage 0 0
+ "2" Pick MoveToPage 1 0
+ "3" Pick MoveToPage 2 0
+ "4" Pick MoveToPage 0 1
+ "5" Pick MoveToPage 1 1
+ "6" Pick MoveToPage 2 1
+ "7" Pick MoveToPage 0 2
+ "8" Pick MoveToPage 1 2
+ "9" Pick MoveToPage 2 2

#####
# Name:     PackWindowUp
# Bound:    Alt+Shift+Up When a window is active
# Purpose:  Interrogate all windows on the current page, find the window with an edge
#           closest to active window, and slide the Active window upto that edge, or
#           the Page edge, if no window is in the way.
#
#           The Wrappers are required to look after the Context while we're testing
#           windows. Could also do it with a load of variables, but this is nicer.
#
#           See PackWindowLeft for a description of the logic (i know it looks a little
#           cryptic).
#
#           Sometimes terminals seem to need WindowRefresh, but 99% of the time it just
#           works, it creates a little flicker so I'll leave it out until it starts to bug
#           me.
#
#           Windows are also Raised, you can disable this.
#
#################
DestroyFunc PackWindowUp
AddToFunc PackWindowUp
+ I SetEnv low_w 0
+ I WindowId $3 Raise
+ I All (CurrentPage !Iconic AcceptsFocus \
        !Shaded) PipeRead "test `expr $[w.y] + $[w.height]` -gt $[low_w] \
        -a `expr $[w.y] + $[w.height]` -lt $0 \
        -a \\( \\( $[w.x] -gt $1 -a $[w.x] -lt `expr $1 + $2` \\) \
            -o \\( $1 -gt $[w.x] -a $1 -lt `expr $[w.x] + $[w.width]` \\) \
            -o \\( $1 -le $[w.x] -a `expr $1 + $2` -ge `expr $[w.x] + $[w.width]` \\) \
            -o \\( $[w.x] -lt $1 -a `expr $[w.x] + $[w.width]` -gt `expr $1 + $2` \\) \
        \\) \
        && echo SetEnv low_w `expr $[w.y] + $[w.height]` \
        || echo Nop"
+ I WindowId $3 AnimatedMove keep $[low_w]p
#+ I WindowId $3 RefreshWindow

AddToFunc PackWrapperUp I NoWindow PackWindowUp $[w.y] $[w.x] $[w.width] $[w.id]

#####
# Name:     PackWindowDown
# Bound:    Alt+Shift+Down When a window is active.
# Purpose:  See PackWindowUp.
#
#################
DestroyFunc PackWindowDown
AddToFunc PackWindowDown
+ I SetEnv high_w $[vp.height]
+ I WindowId $3 Raise
+ I All (CurrentPage !Iconic AcceptsFocus \
        !Shaded) PipeRead "test $[w.y] -lt $[high_w] \
        -a $[w.y] -gt `expr $0 + $4`  \
        -a \\( \\( $[w.x] -gt $1 -a $[w.x] -lt `expr $1 + $2` \\) \
            -o \\( $1 -gt $[w.x] -a $1 -lt `expr $[w.x] + $[w.width]` \\) \
            -o \\( $1 -le $[w.x] -a `expr $1 + $2` -ge `expr $[w.x] + $[w.width]` \\) \
            -o \\( $[w.x] -lt $1 -a `expr $[w.x] + $[w.width]` -gt `expr $1 + $2` \\) \
        \\) \
        && echo SetEnv high_w $[w.y] \
        || echo Nop"
+ I PipeRead "echo WindowId $3 AnimatedMove keep `expr $[high_w] - $4`p"
#+ I WindowId $3 RefreshWindow

AddToFunc PackWrapperDown I NoWindow PackWindowDown $[w.y] $[w.x] $[w.width] $[w.id] $[w.height]

#####
# Name:     PackWindowLeft
# Bound:    Alt+Shift+Left When a window is active
# Purpose:  See PackWindowUp.
#
# The Logic works likes this:
#   1. Set Destination to the Left Edge
#   2. For every window, Run these tests:
#               + Is the Window's Right edge further _Right_ than furthest edge seen yet?
#       And:    + Is it's Right edge Further _Left_ than Target Windows Left edge? (ie, in the way)
#           Yes:
#                   + Does the window start inside Target Window, and end below?
#               Or  + Does it start above, and end inside?
#               Or  + Is it the same vertical position/height/size, or start inside and end inside?
#               Or  + Does it start above, and end below?
#                   Yes:
#                       This is the new Destination.
#                   No:
#                       Nop
#           No:
#               Nop
#   3. Move to Destination.
#
#################
DestroyFunc PackWindowLeft
AddToFunc PackWindowLeft
+ I SetEnv left_w 0
+ I WindowId $3 Raise
+ I All (CurrentPage !Iconic AcceptsFocus \
        !Shaded) PipeRead "test `expr $[w.x] + $[w.width]` -gt $[left_w] \
        -a `expr $[w.x] + $[w.width]` -lt $1 \
        -a \\( \\( $[w.y] -gt $0 -a $[w.y] -lt `expr $0 + $4` \\) \
            -o \\( $[w.y] -lt $0 -a `expr $[w.y] + $[w.height]` -gt $0 \\) \
            -o \\( $[w.y] -ge $0 -a `expr $[w.y] + $[w.height]` -le `expr $0 + $4` \\) \
            -o \\( $[w.y] -lt $0 -a `expr $[w.y] + $[w.height]` -gt `expr $0 + $4` \\) \
        \\) \
        && echo SetEnv left_w `expr $[w.x] + $[w.width]`  \
        || echo Nop"
+ I WindowId $3 AnimatedMove $[left_w]p keep
#+ I WindowId $3 RefreshWindow

AddToFunc PackWrapperLeft I NoWindow PackWindowLeft $[w.y] $[w.x] $[w.width] $[w.id] $[w.height]

DestroyFunc PackWindowRight
AddToFunc PackWindowRight
+ I SetEnv right_w $[vp.width]
+ I WindowId $3 Raise
+ I All (CurrentPage !Iconic AcceptsFocus \
        !Shaded) PipeRead "test $[w.x] -lt $[right_w] \
        -a $[w.x] -gt `expr $1 + $2` \
        -a \\( \\( $[w.y] -gt $0 -a $[w.y] -lt `expr $0 + $4` \\) \
            -o \\( $[w.y] -lt $0 -a `expr $[w.y] + $[w.height]` -gt $0 \\) \
            -o \\( $[w.y] -ge $0 -a `expr $[w.y] + $[w.height]` -le `expr $0 + $4` \\) \
            -o \\( $[w.y] -lt $0 -a `expr $[w.y] + $[w.height]` -gt `expr $0 + $4` \\) \
        \\) \
        && echo SetEnv right_w $[w.x] \
        || echo Nop"
+ I PipeRead "echo WindowId $3 AnimatedMove `expr $[right_w] - $2`p keep"
#+ I WindowId $3 RefreshWindow

AddToFunc PackWrapperRight I NoWindow PackWindowRight $[w.y] $[w.x] $[w.width] $[w.id] $[w.height]

#####
# Name:     WheelToggleShade
# Bound:    Mouse Buttons 4 and 5 (wheel up and down) on Titlebars
# Purpose:  Shade or unshade the window when the Mouse wheel is rolled up or
#           down on the Titlebar. Rolling the Wheel up calls the Function with
#           argument `True` and rolling it down uses `False`, so rolling the wheel
#           down when the window isnt shaded has no effect, which I like :)
#
#################
DestroyFunc WheelToggleShade
AddToFunc WheelToggleShade D WindowShade $0

#####
# Name:     DestroyOnHold
# Bound:    Titlebar Button 2 (X)
# Purpose:  When clicked, Raise the window Immediately.
#           If the button is pressed and released, Close the Window. If it is pressed
#           and held, Destroy it, and issue a Beep to confirm.
#
#           There is a 100ms delay before issuing `Close` so I have a chance to see the
#           animation when the button changes from ActiveDown to ActiveUp :).
#
#################
DestroyFunc DestroyOnHold
AddToFunc DestroyOnHold I Raise
+ C Schedule 100 Close
+ H Destroy
+ H Beep


#####
# Name:     Thumbnail
# Purpose:  Iconify a window with a reduced screenshot of the application
#           Window, looks really cool.
#
#           Uses FvwmEvent to remove the Icon when deiconified.
#
#           Thumbnailing example:
#
# http://www.fvwm.org/screenshots/desktops/Tavis_Ormandy-desk-1152x864/screenshot.jpg
#
# If you have a slow machine, try changing -scale to -sample, the quality of the Icons
# won't be as good, but they are generated much faster.
#
##################
DestroyFunc Thumbnail
AddToFunc Thumbnail
+ I Raise
+ I SetEnv Icon-$[w.id] $[w.iconfile]
+ I ThisWindow (!Shaded Iconifiable !Iconic) PipeRead \
    "xwd -silent -id $[w.id] | convert -scale $[fvwm_icon_size] -frame 1x1 \
    -mattecolor black -quality 0 xwd:- png:$[HOME]/tmp/icon.tmp.$[w.id].png \
    && echo WindowStyle IconOverride, Icon $[HOME]/tmp/icon.tmp.$[w.id].png \
    || echo Nop"
+ I TestRc (Match) Test (f $[HOME]/icons/$[w.miniiconfile]) PipeRead "composite -geometry +2+4 \
    $[fvwm_image_path]/icons/$[w.miniiconfile] $[HOME]/tmp/icon.tmp.$[w.id].png \
    $[HOME]/tmp/icon.tmp.$[w.id].png && echo Nop \
    || echo Beep"
+ I Iconify

# XXX: No need for NoIconOverride.
DestroyFunc DeThumbnail
AddToFunc DeThumbnail
+ I PipeRead "echo WindowStyle Icon \\$\\[Icon-$[w.id]\\]"
+ I UnsetEnv Icon-$[w.id]
+ I Exec exec rm -f $[HOME]/tmp/icon.tmp.$[w.id].png

*FvwmEvent: deiconify DeThumbnail

DestroyFunc IconifyWithScreenshot
AddToFunc IconifyWithScreenshot
+ I echo "Iconnify running"
+ I Raise
+ I PipeRead "import -geometry 64 -frame -resize 64 -silent -window $[w.id] $[HOME]/.fvwm/icon.tmp.$[w.id].png && echo WindowStyle IconOverride, Icon $[HOME]/.fvwm/icon.tmp.$[w.id].png || echo Nop"
+ I Iconify

# FIXME: Make this more useful.
# XXX: This doesnt do much yet, you can play with it if you like.
# Example: http://dev.gentoo.org/~taviso/fvwm_expose.png
DestroyFunc FvwmExpose
AddToFunc FvwmExpose
+ I AddToMenu FvwmExposeMenu ".: e x p o s e :." Title
+ I All (!Iconic !Shaded CurrentPage AcceptsFocus)\
    PipeRead "echo Raise; \
        xwd -silent -id $[w.id] | convert -scale $[fvwm_icon_size] -quality 0 xwd:- \
        png:$[HOME]/tmp/icon.exp.$[w.id].png \
    && echo AddToMenu FvwmExposeMenu \
    %$[HOME]/tmp/icon.exp.$[w.id].png%\\\'\"$[w.name]\"\\\' WindowID $[w.id] WarpToWindow 50 50 \
        && echo AddToMenu FvwmExposeMenu \\\"\\\" Nop \
    || Nop"
+ I Popup FvwmExposeMenu
+ I DestroyMenu FvwmExposeMenu
+ I Exec exec rm -f $[HOME]/tmp/icon.exp.*

# Fvwm uses this function when selecting windows from the WindwList command
# you can make this function do any thing you like, it is executed in the context
# of the selected window.
AddToFunc WindowListFunc I WarpToWindow 50 50

DestroyFunc FuncAutoEnter
AddToFunc FuncAutoEnter I Autohide HiddenConsole 250 500 N

# Example: http://dev.gentoo.org/~taviso/screenshots/browsewall.png
# XXX: Slooooow at first run.
DestroyFunc WallpaperBrowser
AddToFunc WallpaperBrowser
+ I AddToMenu WallpaperBrowserMenu DynamicPopDownAction DestroyMenu WallpaperBrowserMenu
+ I PipeRead 'cd $[fvwm_wallpaper_dir]; \
             test ! -d "$[fvwm_wallpaper_dir]/.thumbs" && mkdir "$[fvwm_wallpaper_dir]/.thumbs"; echo >&2 "dir = $[fvwm_wallpaper_dir]/.thumbs"; \
    for i in "$[fvwm_wallpaper_dir]/"*; do \
        test -f "$[fvwm_wallpaper_dir]/.thumbs/${i##*/}" \
            -a "${i}" -ot "$[fvwm_wallpaper_dir]/.thumbs/${i##*/}" || { \
                convert -quality 0 -scale 32 "${i}" "png:$[fvwm_wallpaper_dir]/.thumbs/${i##*/}" 2>/dev/null \
                    || continue; \
            }; \
        printf "+ %%\\"%s\\"%%\\"%s\\" Exec exec fvwm-root -r %s\\n" \
            "$[fvwm_wallpaper_dir]/.thumbs/${i##*/}" "${i##*/}" "${i}"; \
    done'

####
# These functions modified from the functions provided in the fvwm FAQ.
# http://www.fvwm.org/documentation/faq/#7.17
#################
AddToFunc Autohide
+ I ThisWindow ($0) Deschedule $[w.id]
+ I TestRc (!Match) Deschedule -$[w.id]
+ I ThisWindow ($0) ThisWindow (shaded) AutohideShow $1 $3
+ I TestRc (!Match) All ($0, !shaded) AutohideHide $2 $3

AddToFunc AutohideShow
+ I Schedule $0 -$[w.id] WindowShade $1 off
+ I Schedule $0 -$[w.id] Raise
+ I Schedule $0 -$[w.id] Deschedule $[w.id]
+ I Schedule $0 -$[w.id] Deschedule -$[w.id]

AddToFunc AutohideHide
+ I Schedule $0 $[w.id] WindowShade $1 on
+ I Schedule $0 $[w.id] Deschedule $[w.id]
+ I Schedule $0 $[w.id] Deschedule -$[w.id]

DestroyFunc .
AddToFunc .
+ I SendToModule FvwmPerl preprocess -c -- $*

DestroyFunc SendWindowToPage
AddToFunc SendWindowToPage
+ I SetEnv LAST_WIN_ID $[w.id]
+ I . FvwmButtons -g 144x96+%{$[pointer.x]-$[page.nx]*36-34}%+%{$[pointer.y]-$[page.ny]*24-20}% -transient GridButtons

DestroyFunc MoveLastWindowToPage
AddToFunc MoveLastWindowToPage
+ I WindowId $[LAST_WIN_ID] MoveToPage $0 $1

DestroyFunc CenterViewportOnWindow
AddToFunc CenterViewportOnWindow
+ I FlipFocus
+ I WarpToWindow 50 50
+ I PipeRead "echo Scroll $$((((-$[vp.width]/2)+$[pointer.x])))p $$(((-($[vp.height]/2)+$[pointer.y])))p

# To warp to the top left corner of a window without switching pages
# you can use

AddToFunc my_warptowindow
+ I WindowId root 0 WarpToWindow $[w.x]p $[w.y]p

DestroyFunc SnapshotAllWindows
AddToFunc SnapshotAllWindows
+ I  GotoDesk 0
+ I  GotoPage 0 0
+ I  PipeRead `import -window root /tmp/desktop-000.png >/dev/null`
+ I  GotoPage 0 1
+ I  PipeRead `import -window root /tmp/desktop-001.png >/dev/null`
+ I  GotoPage 1 0
+ I  PipeRead `import -window root /tmp/desktop-010.png >/dev/null`
+ I  GotoPage 1 1
+ I  PipeRead `import -window root /tmp/desktop-011.png >/dev/null`
+ I  GotoDesk 1
+ I  GotoPage 0 0
+ I  PipeRead `import -window root /tmp/desktop-100.png >/dev/null`
+ I  GotoPage 0 1
+ I  PipeRead `import -window root /tmp/desktop-101.png >/dev/null`
+ I  GotoPage 1 0
+ I  PipeRead `import -window root /tmp/desktop-110.png >/dev/null`
+ I  GotoPage 1 1
+ I  PipeRead `import -window root /tmp/desktop-111.png >/dev/null`



DestroyFunc Screenshot 
AddToFunc Screenshot 
+ I      PipeRead `for ((x=0; x < $[desk.pagesx]; x++)); do                          \
	            for ((y=0; y < $[desk.pagesy]; y++));                           \
		     do                                                            \
                          echo GotoPage ${x} ${y};                                   \
		        xwd -root -silent -out $[FVWM_USERDIR]/page_${x}_${y}.xwd; \
	              done;                                                         \
                   done;                                                             \
	          montage -geometry $[vp.width]x$[vp.height] -tile                  \
                     $[desk.pagesx]x$[desk.pagesy] $[FVWM_USERDIR]/page_*_*.xwd      \
	              png:$[HOME]/screenshot.png; rm -f $[FVWM_USERDIR]/page_*_*.xwd `

Key F12 A S Screenshot 

