# ============================================================
# FVWM3 configuration
# ============================================================
#
# Clean, minimal configuration for the current FVWM3 desktop.
# Sections are grouped by function so that individual settings
# can be changed without having to trace unrelated definitions.
# ============================================================


# ============================================================
# 1. Screen and panel geometry
# ============================================================

# Keep all panel dimensions here.
# The screen width itself is detected automatically by FVWM.
InfoStoreAdd panel_height 32
InfoStoreAdd menu_width 70
InfoStoreAdd battery_width 80
InfoStoreAdd clock_width 80
InfoStoreAdd pager_width 90

# Calculate the width available for the task list:
# screen width minus all fixed-width panel elements.
PipeRead 'w=$[vp.width]; \
    t=$((w - 70 - 80 - 80 - 90)); \
    echo "InfoStoreAdd screen_width $w"; \
    echo "InfoStoreAdd tasklist_width $t"'

# The variables above are used later as:
#   $[infostore.screen_width]
#   $[infostore.tasklist_width]
#   $[infostore.panel_height]
#
# This makes the panel adapt automatically to different screen widths.


# ============================================================
# 2. Window appearance and behaviour
# ============================================================

# Window title font.
Style * Font "xft:Sans:size=14"

# Border thickness and resize-handle width.
Style * BorderWidth 2, HandleWidth 6

# Clicking a window gives it focus and raises it.
Style * ClickToFocus, ClickToFocusRaises

# Move windows with their contents visible instead of showing
# only an outline while dragging.
OpaqueMoveSize unlimited


# ============================================================
# 3. Title-bar buttons and window movement
# ============================================================

# FVWM title-bar button numbering:
#   odd numbers  = left side
#   even numbers = right side
#
# Current layout:
#   left:  close
#   right: iconify | restore | maximize

Mouse 1 1 A Close
Mouse 1 6 A Iconify
Mouse 1 4 A Maximize False
Mouse 1 2 A Maximize True

# Raise an window when its title bar is clicked.
# If the mouse is moved while the button is held, move the window.
DestroyFunc MoveOrRaise
AddToFunc MoveOrRaise
+ I Raise
+ M Move

Mouse 1 T A MoveOrRaise

# Resize by dragging the frame or side handles.
Mouse 1 FS A Resize


# ============================================================
# 4. Main menu
# ============================================================

MenuStyle * Font "xft:Sans:size=14"

DestroyMenu MainMenu
AddToMenu MainMenu "FVWM" Title
+ "Terminal"     Exec exec xfce4-terminal --color-bg=black
+ "Firefox"      Exec exec firefox
+ "Thunar"       Exec exec env GTK_THEME=Adwaita:dark thunar
+ "Mousepad"     Exec exec env GTK_THEME=Adwaita:dark mousepad
+ ""             Nop
+ "Restart FVWM" Restart
+ "Exit FVWM"    Quit

# Right click on the root window (desktop) opens the main menu.
Mouse 3 R A Menu MainMenu


# ============================================================
# 5. Keyboard shortcuts
# ============================================================

# Alt+Enter opens a terminal.
Key Return A M Exec exec xfce4-terminal --color-bg=black

# The following hardware keys are FreeBSD/MacBook-specific.
# Display brightness
Key F1 A N Exec exec backlight decr 5
Key F2 A N Exec exec backlight incr 5
# Keyboard backlight
Key F5 A N Exec exec asmctl key down
Key F6 A N Exec exec asmctl key up
# Audio controls
Key F10 A N Exec exec mixer vol.mute=toggle
Key F11 A N Exec exec mixer vol=-5%
Key F12 A N Exec exec mixer vol=+5%

# ============================================================
# 6. Virtual desktop
# ============================================================

# One desktop consisting of two pages side by side.
DesktopSize 2x1


# ============================================================
# 7. Panel colours
# ============================================================

# Normal panel/task-button colour.
Colorset 20 fg=black, bg=#a0a0a0

# Focused/selected task-button colour.
Colorset 21 fg=white, bg=#806080


# ============================================================
# 8. Bottom panel (FvwmButtons)
# ============================================================

# Reserve the panel height at the bottom of the screen so
# maximized windows do not cover the panel.
EwmhBaseStruts 0 0 0 $[infostore.panel_height]

Style "BottomPanel" !Title, !Borders, !Handles, Sticky, \
                    StaysOnTop, WindowListSkip, FixedPosition

DestroyModuleConfig BottomPanel: *

# The panel always spans the full current viewport width.
# One FvwmButtons column corresponds to one horizontal pixel,
# which lets the widths below be specified directly in pixels.
*BottomPanel: Geometry $[infostore.screen_width]x$[infostore.panel_height]+0-0
*BottomPanel: Rows 1
*BottomPanel: Columns $[infostore.screen_width]
*BottomPanel: Colorset 20
*BottomPanel: Font "xft:Sans:size=12"
*BottomPanel: Frame 1
*BottomPanel: Padding 2 2

# Main menu button.
*BottomPanel: ($[infostore.menu_width]x1, Title "FVWM", \
    Action(Mouse 1) "Menu MainMenu Root 0 o100-32p")

# Task list: all currently open windows on the current page.
*BottomPanel: ($[infostore.tasklist_width]x1, Left, \
    Swallow TaskBarIcons 'Module FvwmIconMan TaskBarIcons')

# Battery / AC indicator.  The text is updated by UpdateBattery.
*BottomPanel: ($[infostore.battery_width]x1, Id Battery, Title "BAT:--%")

# Clock.  The text is updated by UpdateClock.
*BottomPanel: ($[infostore.clock_width]x1, Id Clock, Title "--:--")

# Two-page desktop pager.
*BottomPanel: ($[infostore.pager_width]x1, \
    Swallow(NoClose) "FvwmPager" 'Module FvwmPager 0 0')


# ============================================================
# 9. Task list (FvwmIconMan)
# ============================================================

DestroyModuleConfig TaskBarIcons: *

*TaskBarIcons: IconName TaskBarIcons
*TaskBarIcons: Title ""
*TaskBarIcons: UseWinList true
*TaskBarIcons: Resolution page

*TaskBarIcons: Font "xft:Sans:size=11"
*TaskBarIcons: ManagerGeometry 1x1
*TaskBarIcons: ButtonGeometry 140x32
*TaskBarIcons: MaxButtonWidth 160


# Draw application icons in task buttons.  Keeping icon drawing
# enabled also avoids the text-rendering problem seen with DrawIcons none.
*TaskBarIcons: DrawIcons always

*TaskBarIcons: Format "%t"
*TaskBarIcons: Sort id
*TaskBarIcons: ReliefThickness 1

*TaskBarIcons: Background #a0a0a0
*TaskBarIcons: Foreground black
*TaskBarIcons: PlainColorset 20
*TaskBarIcons: FocusColorset 21
*TaskBarIcons: SelectColorset 21
*TaskBarIcons: FocusAndSelectColorset 21

# Clicking a task button raises and focuses that window.
*TaskBarIcons: Action Mouse 1 A sendcommand PanelWindowClick

DestroyFunc PanelWindowClick
AddToFunc PanelWindowClick
+ I ThisWindow (Iconic) Iconify
+ I ThisWindow Raise
+ I ThisWindow FlipFocus


# ============================================================
# 10. Pager
# ============================================================

Style "FvwmPager" !Title, !Borders, !Handles, WindowListSkip

DestroyModuleConfig FvwmPager: *

# The pager is swallowed by BottomPanel, so it needs no
# standalone Geometry setting.
*FvwmPager: NoDeskLabels
*FvwmPager: Back #808080


# ============================================================
# 11. Dynamic panel indicators
# ============================================================

# Show AC:<percent>% while connected to mains power and
# BAT:<percent>% while running on battery.
DestroyFunc UpdateBattery
AddToFunc UpdateBattery
+ I PipeRead 'if [ "$(sysctl -n hw.acpi.acline)" = "1" ]; then p=AC; else p=BAT; fi; printf "SendToModule BottomPanel ChangeButton Battery Title %s:%s%%\n" "$p" "$(sysctl -n hw.acpi.battery.life)"'

# Update the panel clock in 24-hour HH:MM format.
DestroyFunc UpdateClock
AddToFunc UpdateClock
+ I PipeRead 'echo "SendToModule BottomPanel ChangeButton Clock Title $(date +%H:%M)"'


# ============================================================
# 12. Session startup
# ============================================================

# InitFunction runs only when FVWM initially starts.
# Picom is external to FVWM and survives an FVWM Restart, so it
# must not be launched again on every restart.
DestroyFunc InitFunction
AddToFunc InitFunction
+ I Exec exec picom --vsync --frame-opacity 1

# StartFunction also runs after an FVWM Restart.
# FVWM modules are restarted here because they do not survive it.
DestroyFunc StartFunction
AddToFunc StartFunction
+ I Module FvwmButtons BottomPanel

# Give the panel one second to appear before its first update.
+ I Schedule 1000 UpdateBattery
+ I Schedule 1000 UpdateClock

# Periodic updates.
+ I Schedule Periodic 30000 UpdateBattery
+ I Schedule Periodic 10000 UpdateClock
