The F Virtual Window Manager
FVWM is an EWMH and ICCCM compliant stacking window manager for X11. Its configuration involves editing plain text files. From official Github mirror:
Fvwm is intended to have a small memory footprint but a rich feature set, be extremely customizable and extendible, and have a high degree of Motif mwm compatibility.
FVWM substantially allows one to build a fully-fledged lightweight desktop environment from scratch, with an almost unparalleled degree of freedom. Although using FVWM does not require any knowledge of programming languages, it is possible to extend it with M4, C, and Perl preprocessing.
In September 2020, the 3rd major version of the F Virtual VM was finally released; as a consequence, this guide (first written in Italian in May 2020) has been updated to rather use the latest version (config has been tested and is working on the new release), which was originally packaged for pkgsrc, and is currently maintained by, @nia
Let's get started
First we'll need to install fvwm;
$ cd /usr/pkgsrc/wm/fvwm3 && make install clean clean-depends
How it Works
Most of the settings below can be easily interpreted by looking up the fvwm(1) man page. Nonetheless, functions and bindings can prove quite hard to understand at first sight, so before we dive into my FVWM configuration, I'll provide you with a quick overview.
===== Functions Syntax
+ I = Immediately
+ C = Single Click
+ D = Double Click
+ H = Hover
+ M = Motion, AKA Click and Drag
===== Syntax and Buttons/Windows/Mods/Mouse IDs for Bindings
# Default Binding Syntax
Key {(window)} [key] [Context] [Modifier] [Action]
Mouse {(window)} [button] [Context] [Modifier] [Action]
Button: 0=any, 1, 2 or 3
| Context: R=RootWdw, W=AppsWdw, T=TitleBar, S=Sides
| | F=Frame (corners), I=IconWindow, 0-9=WindowButtons
| |
| | Modifiers: None,Control,Shift,Meta,Any,4=hyper
| | | Function
+------ +------ +------ +-------
# Window Buttons and Window ID
+--------------------------------------------------------+
| Root Window |
| Icon |
| |
| F------------------------S--------------------------F| |
| | 1 3 5 7 9 Title Bar (T) 0 8 6 4 2 | |
| +----------------------------------------------------+ |
| | | |
| S W S |
| | | |
| F------------------------S--------------------------F |
| |
# Contexts:
R = Root Window
W = Application Window (anywhere inside borders)
F = Frame Corners
S = Frame Sides
T = Title Bar
I = Icon (Iconified in the IconBox)
A = Anywhere
# Valid Modifiers
N = None
C = Control
S = Shift
M = Meta (Alt)
4 = Hyper (Start/Win Key)
L = Caps Lock
A = Any modifier
# Mouse Buttons Numbering
1 = left button
2 = middle button (pressing the scroll wheel)
3 = right button
4 = turn scroll wheel up
5 = turn scroll wheel down
6 = push scroll wheel left
7 = push scroll wheel right
8 = 4th button (aka browser backward button)
9 = 5th button (aka browser forward button)
Configuring FVWM
a) Premises
What this configuration is: an attempt to provide a comfortable titlebar-less stacking wm environment for modern use, with simple, flat, dark-cyan decorations and a strong focus on keyboard bindings. The setup includes full EWMH compliance, basic tiling functions, dynamic focus change, icons and thumbnails as two alternative minimizing methods, fullscreen switch, alt-tab window cycling, window renaming, virtual desktops, multi-monitor layout, xf86/fn multimedia key bindings and more.
What this configuration is not: the setup shown in this tutorial tries to stay as lightweight as possible and doesn't make use of any additional Fvwm module but the core one and the FvwmPager one; no custom widgets or status bars through FvwmButtons, no FvwmEvent/FvwmScript/FvwmForm, no Perl extension whatsoever. You may still want to enable animations (configured, but disabled by default).
Dependencies: x11/rxvt-unicode is assumed to be the terminal emulator of choice, though this can be obviously changed to reflect one's preference. The 'Thumbnail' and 'Screenshot' functions require graphics/ImageMagick, graphics/netpbm, while the 'savexclip' and 'title' scripts require x11/xclip and x11/xwit respectively. All scripts sending desktop notifications through libnotify naturally expect a notify-daemon to be running: author personally recommends x11/dunst (requires dbus). The setup also makes heavy use of the 'nu' bitmap font coming bounded with fonts/artwiz-fonts. Adjusting screen brightness and suspending implies changing ''sysctl'' values and requires therefore root privileges: you can use security/ssh-askpass to get a simple graphical password prompt whenever needed. x11/xpmicons is used to create some custom application icons (especially terminal ones based on curses/slang): add as many more as you wish. Totally optional: fvwm's autostart script launches x11/xautolock in background to enable automatic screen locking through x11/xlockmore. As a side note, please notice also that 'pcmanfm' requires sysutils/gvfs in order to enable support for Trash Can, Devices and Network mounts.
b) Preliminary Tasks
Create the required folders in you $HOME for FVWM to use
$ for d in icons images scripts tmp wallpapers
do mkdir -p ~/.fvwm/${d}
done
c) fvwmrc
Below follows the relevant ~/.fvwm/config; it will be parsed upon startup.
###############=
#---- GLOBAL SETTINGS
###############=
# Set up 4 Desktops, 4 pages each
DesktopSize 2x2
DesktopName 0 FVWM Desktop (1)
DesktopName 1 FVWM Desktop (2)
DesktopName 2 FVWM Desktop (3)
DesktopName 3 FVWM Desktop (4)
# Maximum delay in milliseconds between a button press and a button
# release for the Function command to consider the action a mouse click
ClickTime 250
# Move al windows as solid ones
OpaqueMoveSize -1
# Snap edges when windows are moved close to each other
SnapAttraction 10 All Screen
XorValue 55555
# Disable EdgeScrolling but make it possible
# to move windows over the screen edge
EdgeScroll 0 0
EdgeResistance -1
EdgeThickness 2
EdgeCommand Left nop
# Installed colormap follows the windows the cursor is in
ColormapFocus FollowsMouse
# honor window's own idea of placement
EWMHUseStackingOrderHints
# 3 pixel screen edges
EwmhBaseStruts 3 3 3 3
# Virtaul layers in use for windows to overlap
DefaultLayers 2 4 6
# Ignore Num/Scroll-Lock as modifiers
IgnoreModifiers L25
# a pixel 10 mouse movement with whatever
# button pressed is assumed to be a drag
MoveThreshold 10
# Always hide the geometry info box
HideGeometryWindow Move, Resize
# Small fixes for modern workflows
BugOpts FlickeringMoveWorkaround True, EWMHIconicStateWorkaround True
# Default terminal emulator
InfoStoreAdd terminal urxvt
# Default launcher
InfoStoreAdd runcmd "dmenu_run -b -p '>>' -fn 'nu-8' -nb '#151515' -nf '#D7D0C7' -sb '#151515' -sf '#4E9FB1'"
# Default web browser
InfoStoreAdd browser seamonkey
###############=
#---- PATHS
###############=
ImagePath $[FVWM_DATADIR]/pixmaps:/usr/pkg/include/X11/pixmaps
SetEnv FVWM_IMG $[FVWM_USERDIR]/images
SetEnv FVWM_ICON $[FVWM_USERDIR]/icons
SetEnv FVWM_S $[FVWM_USERDIR]/scripts
SetEnv FVWM_WALL $[FVWM_USERDIR]/wallpapers
SetEnv FVWM_TMP $[FVWM_USERDIR]/tmp
###############=
#---- COLORSETS
###############=
#--- Window Deco
Colorset 3 fg #505050, bg #171717
Colorset 4 fg #808080, bg #151515
Colorset 5 fg #D7D0C7, bg #4E9FB1
Colorset 6 fg #909090, bg #151515, sh #4E9FB1, hi #4E9FB1
Colorset 7 fg #D7D0C7, bg #151515, sh #eb928e, hi #151515
Colorset 8 fg #D7D0C7, bg #151515, sh #4E9FB1, hi #4E9FB1
#--- Pager
Colorset 9 fg #4E9FB1, bg #151515, sh #eeeeee, hi #303030
Colorset 10 fg #bbbbbb, bg #303030, sh #eeeeee, hi #303030
###############=
#---- STYLES
###############=
#--- General
Style * PositionPlacement UnderMouse, GrabFocusOff
Style * NoPPosition, ResizeOpaque
Emulate MWM
DefaultFont "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
HideGeometryWindow Always
SnapAttraction 5 SameType Screen
SnapGrid 5 5
XorValue 55555
Style * DecorateTransient, DontRaiseTransient
Style * DontLowerTransient, StackTransientParent
Style * GrabFocusTransientOff
Style * WindowShadeSteps 20, WindowShadeScrolls
#--- Windows
DestroyDecor MyDecor
AddToDecor MyDecor
+ TitleStyle RightJustified Height 18
+ ButtonStyle 2 ActiveUp Vector 6 30x50@3 40x40@3 50x50@3 50x65@4 40x55@3 30x65@3 -- Flat
+ ButtonStyle 2 ActiveDown Vector 6 30x50@3 40x40@3 50x50@3 50x65@4 40x55@3 30x65@3 -- Flat
+ ButtonStyle 2 Inactive Vector 6 30x50@3 40x40@3 50x50@3 50x65@4 40x55@3 30x65@3 -- Flat
+ ButtonStyle 4 ActiveUp Vector 6 40x50@3 30x40@3 40x30@3 55x50@4 40x40@3 55x30@3 -- Flat
+ ButtonStyle 4 ActiveDown Vector 6 40x50@3 30x40@3 40x30@3 55x50@4 40x40@3 55x30@3 -- Flat
+ ButtonStyle 4 Inactive Vector 6 40x50@3 30x40@3 40x30@3 55x50@4 40x40@3 55x30@3 -- Flat
+ ButtonStyle 6 ActiveUp Vector 6 30x20@3 40x30@3 50x20@3 50x30@4 40x40@3 30x30@3 -- Flat
+ ButtonStyle 6 ActiveDown Vector 6 30x20@3 40x30@3 50x20@3 50x30@4 40x40@3 30x30@3 -- Flat
+ ButtonStyle 6 Inactive Vector 6 30x20@3 40x30@3 50x20@3 50x30@4 40x40@3 30x30@3 -- Flat
+ TitleStyle -- Flat
+ BorderStyle Simple -- NoInset Flat
+ ButtonStyle All -- UseTitleStyle
Style * UseDecor MyDecor
Style * Font "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
Style * NoTitle
Style * BorderWidth 2, HandleWidth 2
Style * BorderColorset 4
Style * HilightBorderColorset 5
Style * SloppyFocus
Style * MouseFocusClickRaises
Style * FPClickRaisesFocused
Style * FPGrabFocus
Style * FPReleaseFocus
Style * FPLenient
Style * FPSortWindowlistByFocus
Style * FPIgnoreRaiseClickMotion
Style * NoPPosition
Style * TileCascadePlacement
Style * DecorateTransient
Style * StackTransientParent
Style * EWMHUseStackingOrderHints
Style * EdgeMoveDelay 350
Style * EdgeMoveResistance 25
Style * Font "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
Style * WindowShadeSteps 64
Style * WindowShadeShrinks
Style * HintOverride
Style * ResizeOpaque
Style * ResizeHintOverride
Style * MwmDecor
Style * MwmBorder
Style * MwmButtons
Style * MwmFunctions
Stule * MiniIcon
Style * SnapGrid 5 5
#--- Cursors
CursorStyle ROOT left_ptr
CursorStyle TITLE left_ptr
CursorStyle DEFAULT left_ptr
CursorStyle SYS left_ptr
CursorStyle MENU left_ptr
CursorStyle WAIT left_ptr
BusyCursor DynamicMenu True, Read True, Wait True
#--- Menus
MenuStyle * PopupDelayed, PopupDelay 300, PopdownImmediately, \
PopupOffset 10 95, TitleWarpOff TitleUnderlines2, \
SeparatorsShort, TrianglesSolid, AnimationOff, \
AutomaticHotkeysOff, BorderWidth 2, PopupAsSubmenu, \
HoldSubmenus, SubmenusRight, ItemFormat "%|%10.10l%5.5>%|", \
VerticalItemSpacing 4 4, VerticalTitleSpacing 3 3, \
MenuColorset 6, ActiveFore, Hilight3DOff, TitleColorset 7, \
ActiveColorset 7, Font "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
#--- Pager
Style "FvwmPager" !Title, !Handles, !Borders, !Maximizable, \
Sticky, WindowListSkip, CirculateSkip, !Closable, \
StaysOnBottom, FixedPosition, FixedSize, !Iconifiable, \
MouseFocusClickRaises, Layer 0 2, State 2, WindowListSkip, \
CirculateSkip, MiniIcon
#--- Ident
*FvwmIdent: Colorset 4
*FvwmIdent: Font "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
#--- XClock
Style "XClock" Sticky, !Title, !Handles, !Borders, \
!Maximizable, WindowListSkip, CirculateSkip, !Closable, \
StaysOnBottom, FixedPosition, FixedSize, !Iconifiable, \
MouseFocusClickRaises, Layer 0 2, State 2, WindowListSkip, \
CirculateSkip
###############=
#---- FUNCTIONS
###############=
# Startup Modules
DestroyFunc StartFunction
AddToFunc StartFunction
+ I Module FvwmPager
# + I Module FvwmAnimate
# Startup Sript
DestroyFunc InitFunction
AddToFunc InitFunction
+ I Test (F $[FVWM_USERDIR]/autostart)\
Exec exec /bin/sh $[FVWM_USERDIR]/autostart
+ I Exec exec /bin/sh $[FVWM_S]/autoxrandr
+ I Exec exec fvwm-root -r $[FVWM_WALL]/bg4.png
# Basic Fuctions
DestroyFunc RestartFunction
AddToFunc RestartFunction
+ I Nop
+ I Exec /bin/sh $[FVWM_S]/autoxrandr
DestroyFunc SessionInitFunction
AddToFunc SessionInitFunction
+ I Nop
DestroyFunc SessionRestartFunction
AddToFunc SessionRestartFunction
+ I Nop
DestroyFunc FvwmDeleteOrDestroy
AddToFunc FvwmDeleteOrDestroy
+ H Nop
+ M Nop
+ C Delete
+ D Destroy
DestroyFunc FvwmIconifyOrShade
AddToFunc FvwmIconifyOrShade
+ C Thumbnail
DestroyFunc FvwmMaximize
AddToFunc FvwmMaximize
+ H Nop
+ M Nop
+ C Maximize $0 $1
DestroyFunc FvwmMoveOrIconify
AddToFunc FvwmMoveOrIconify
+ M Move
+ D Iconify
DestroyFunc FvwmWindowShade
AddToFunc FvwmWindowShade
+ D WindowShade $0
# Suckless WindowList
AddToFunc PickWindow
+ I WindowList (CurrentPage) CurrentDesk NoDeskNum, \
NoIcons, NoSticky, IconifiedAtEnd, \
SelectOnRelease, MaxLabelWidth 45
# Raise & Move / Shade
DestroyFunc Move-or-Raise
AddToFunc Move-or-Raise
+ I Raise
+ M Move
+ D WindowShade
# Move to Bottom Layer/Unmaximize
AddToFunc MoveLower
+ I Layer 0 4
+ C Lower
+ M ThisWindow (Maximized) Maximize false
+ D RaiseLower
# Automatic IconBox Elements Rearrange
AddToFunc Deiconify-and-Rearrange
+ I Iconify
+ I All (CurrentPage, Iconic) PlaceAgain Icon
DestroyFunc Move-or-Iconify
AddToFunc Move-or-Iconify
+ I Raise
+ M Move
+ D Deiconify-and-Rearrange
# Raise & Resize / (Undo)Lower
DestroyFunc Resize-or-Raise
AddToFunc Resize-or-Raise
+ I Raise
+ M Resize
+ D RaiseLower
# Maximize/Expand with EWMH compliance
AddToFunc Max
+ C Maximize ewmhiwa 100 100
+ M Maximize ewmhiwa growonlayers $[w.layer] -1 grow grow
AddToFunc VerMax
+ I Maximize ewmhiwa 0 100
AddToFunc HorMax
+ I Maximize ewmhiwa 100 0
# Toggle FullScreen On/Off
AddToFunc FullScreen
+ I ThisWindow (Maximized) Fullscreen-Stop
+ I TestRc (False) ThisWindow (!Maximized) FullScreen-Start
AddToFunc FullScreen-Start
+ I ThisWindow (Maximized) WindowStyle Title, Borders
+ I TestRc (!Match) WindowStyle !Title, \
!Borders, FixedSize, FixedPosition
+ I TestRc (!Match) Raise
+ I TestRc (!Match) UpdateStyles
+ I Maximize ewmhiwa 100 100
+ I SetEnv CurrentWindowState_$[w.id] Maximize
AddToFunc FullScreen-Stop
+ I DestroyWindowStyle
+ I UpdateStyles
+ I ThisWindow (Maximized) Maximize
# Tiling
AddToFunc TileLeft
+ I ThisWindow (!Shaded, !Iconic) Maximize 50 100
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move +0 +0
AddToFunc TileRight
+ I ThisWindow (!Shaded, !Iconic) Maximize 50 100
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move -0 +0
AddToFunc TileTop
+ I ThisWindow (!Shaded, !Iconic) Maximize 100 50
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move +0 +0
AddToFunc TileBottom
+ I ThisWindow (!Shaded, !Iconic) Maximize 100 50
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move +0 -0
AddToFunc TileTopLeft
+ I ThisWindow (!Shaded, !Iconic) Maximize 50 50
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move +0 +0
AddToFunc TileTopRight
+ I ThisWindow (!Shaded, !Iconic) Maximize 50 50
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move -0 +0
AddToFunc TileBottomLeft
+ I ThisWindow (!Shaded, !Iconic) Maximize 50 50
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move +0 -0
AddToFunc TileBottomRight
+ I ThisWindow (!Shaded, !Iconic) Maximize 50 50
+ I ThisWindow (Maximized, !Shaded, !Iconic) Move -0 -0
# Increase/Decrease Window Size by 10 lines
AddToFunc IncVerticalSize
+ I ThisWindow (!Shaded, !Iconic) Resize keep w+10c
AddToFunc IncHorizontalSize
+ I ThisWindow (!Shaded, !Iconic) Resize w+10c keep
AddToFunc DecVerticalSize
+ I ThisWindow (!Shaded, !Iconic) Resize keep w-10c
AddToFunc DecHorizontalSize
+ I ThisWindow (!Shaded, !Iconic) Resize w-10c keep
# Dynamically Circulate Focus Across Windows
AddToFunc Raise-and-FlipFocus
+ I Raise
+ I FlipFocus
AddToFunc CirculateFocus
+ I Raise-and-FlipFocus
+ I WarpToWindow !raise 5 5
# Loads the man page $0 in an terminal
DestroyFunc ViewManPage
AddToFunc ViewManPage
+ I Exec exec $[infostore.terminal] -g 80x40 \
-n "Manual Page - $0" -T "Manual Page - $0" -e man "$0"
# Circulate amid terminal windows
AddToFunc ToTerm
+ I Current (State 3, "$0") Break
+ I Next (State 3, "$0") FocusTerm
AddToFunc FocusTerm
+ I Iconify False
+ I Raise-and-FlipFocus
+ I WarpToWindow 80 20
# Go to 'x' Page (Focusing first not Iconified/Shaded Window)
AddToFunc GotoPageFocus
+ I GotoPage $*
+ I PointerWindow (CurrentPage, !Sticky, !Shaded, !Iconic) Focus
+ I TestRc (!Match) Next (CurrentPage, !Sticky, \
!Shaded, !Iconic) Raise-and-Focus
# Move 'Window' to 'x' Page, Go to $x (focusing $Window)
AddToFunc MoveAndGotoPage
+ I MoveToPage $*
+ I GotoPageFocus $*
# Thumbnails
DestroyFunc Thumbnail
AddToFunc Thumbnail
+ SetEnv fvwm_thumbnailing 1
+ I Raise
+ I SetEnv Icon-$[w.id] $[w.iconfile]
+ I ThisWindow (!Shaded Iconifiable !Iconic) PipeRead "xwd -silent -id $[w.id] | \
convert -scale $$(($[w.width]/5)) -adaptive-resize 160x120^ -gravity center -crop 160x120+0+0 \
+repage -frame 1x1 -mattecolor black -quality 0 xwd:- png:$[FVWM_TMP]/icon.tmp.$[w.id].png && echo Nop"
# echo WindowStyle IconOverride, Icon $[FVWM_TMP]/icon.tmp.$[w.id].png || echo Nop"
+ I TestRc (Match) Test (f $[fvwm_icon]/$[w.iconfile], f $[FVWM_TMP]/icon.tmp.$[w.id].png) \
PipeRead "composite -geometry +2+4 $[fvwm_icon]/$[w.iconfile] $[FVWM_TMP]/icon.tmp.$[w.id].png \
$[FVWM_TMP]/icon.tmp.$[w.id].png && echo WindowStyle IconOverride, Icon $[FVWM_TMP]/icon.tmp.$[w.id].png || echo Nop"
+ I TestRc (NoMatch) WindowStyle IconOverride, Icon $[FVWM_TMP]/icon.tmp.$[w.id].png
+ I Iconify
+ SetEnv fvwm_thumbnailing 2
DestroyFunc DeThumbnail
AddToFunc DeThumbnail
+ I PipeRead "echo WindowStyle Icon \\$\\[Icon-$[w.id]\\]"
+ I UnsetEnv Icon-$[w.id]
+ I Exec exec rm -f $[FVWM_TMP]/icon.tmp.$[w.id].png
# Window Screenshots
AddToFunc Screenshot
+ I Exec exec xwd -id $w -out $[FVWM_IMG]/$(echo shot.$(date +'%Y%M%d%H%m%S')).xwd
+ I PipeRead 'for i in $[FVWM_IMG]/*; \
do sleep 1; sh $[FVWM_S]/xwd2png $i > /dev/null 2>&1; done'
###############=
#---- PAGER
###############=
DestroyModuleConfig FvwmPager: *
*FvwmPager: Geometry 160x90-3-3
*FvwmPager: Colorset * 9
*FvwmPager: HilightColorset * 9
*FvwmPager: BalloonColorset * 9
*FvwmPager: BalloonBorderWidth 1
*FvwmPager: BalloonStringFormat %i
*FvwmPager: WindowColorsets 3 10
*FvwmPager: Font "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
*FvwmPager: Balloons All
*FvwmPager: BalloonFont "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
*FvwmPager: BallonYOffset +2
*FvwmPager: UseSkipList
*FvwmPager: Rows 1
#*FvwmPager: SmallFont 5x8
###############=
#---- ICONBOX
###############=
Style * IconBox 48x762+3+3, IconFill Left Top, IconGrid 10 10, \
IconTitleFormat %i, IconTitleRelief, IconBackgroundRelief 1, \
IconBackgroundPadding 0, IconSize -1 -1, IconTitleColorset 6, \
IconBackgroundColorset 6, HilightIconTitleColorset 8, \
IconFill top bottom
# Icons Style
Style * IconFont "-artwiz-nu-medium-r-normal--11-110-75-75-p-90-iso10646-1"
Style * StickyIcon, !StickyStippledIconTitle
# Custom Icons
Style XTerm IconOverride, Icon xterm2.xpm, State 3
Style URxvt IconOverride, Icon term.xpm, State 3
Style Seamonkey IconOverride, Icon netscape3.xpm
Style Pcmanfm IconOverride, Icon xfm_icon.xpm
Style nnn IconOverride, Icon xfm_icon.xpm
Style slrn IconOverride, Icon xnews.xpm
Style zathura IconOverride, Icon Document.xpm
Style irssi IconOverride, Icon netdup.xpm
Style mutt IconOverride, Icon mail2.xpm
Style Thunderbird IconOverride, Icon mail2.xpm
Style cmus IconOverride, Icon MusicSound.dir.xpm
###############=
#---- ANIMATIONS
###############=
SetAnimation 10 -.01 0 .01 .03 .08 .18 .3 \
.45 .6 .75 .85 .90 .94 .97 .99 1.0
*FvwmAnimate: Effect Twist
*FvwmAnimate: Width 1
*FvwmAnimate: Color grey
*FvwmAnimate: Iterations 16
*FvwmAnimate: Delay 3
*FvwmAnimate: Twist 6
###############=
#---- MOUSE BINDINGS
###############=
#--- [But][Context][Mod] [Action]
# Root Window (Desktop):
Mouse 1 R A Menu RootMenu Nop
Mouse 3 R A PickWindow
Mouse 2 R A FvwmExpose
# TitleBar Buttons:
Mouse 0 1 A Menu Window-Ops
Mouse 1 2 A Max
Mouse 3 2 A ThisWindow (Maximized) Maximize false
Mouse 0 2 M FullScreen
Mouse 0 3 A MoveLower
Mouse 0 4 A Iconify
# Borders/Icons:
Mouse 1 FS A Resize-or-Raise
Mouse 1 TS A Move-or-Raise
Mouse 1 I A Move-or-Iconify
Mouse 3 I A Deiconify-and-Rearrange
Mouse 3 FST A Menu Window-Ops Nop
Mouse 2 TSIF A RaiseLower
# Scrollwheel to go up/down Pages
Mouse 4 R A GotoPageFocus +0p -1p
Mouse 5 R A GotoPageFocus +0p +1p
# Scrollwheel (+S) to go left/right Pages
Mouse 4 R S GotoPageFocus +1p -0p
Mouse 5 R S GotoPageFocus -1p +0p
# Mouse-grab with Alt for various Window-Ops
Mouse 1 W M Move-or-Raise
Mouse 3 W M Resize-or-Raise
Mouse 3 W C Menu Window-Ops Nop
Mouse 1 W 4M Thumbnail
Mouse 3 W 4M Max
Mouse 3 W SM Fullscreen
Mouse 1 W SM RaiseLower
Mouse 1 W CM Iconify
Mouse 3 W CM WindowShade
Mouse 1 W C4M Stick
Mouse 3 W C4M Close
Mouse 1 W S4M Title
###############=
#---- KEY BINDINGS
###############=
#--- [Key][Context][Mod] [Action]
# Alt + Arrow | Moves window by 15 pixels
Key Left A M Move w-15p w+0p
Key Right A M Move w+15p w+0p
Key Up A M Move w+0p w-15p
Key Down A M Move w+0p w+15p
# Ctrl-Alt + Arrow | Resizes window by 10 pixels
Key Left A CM DecHorizontalSize
Key Right A CM IncHorizontalSize
Key Up A CM DecVerticalSize
Key Down A CM IncVerticalSize
# Shift + Arrow | Scrolls by 1 page.
Key Left A S Scroll -100 0
Key Right A S Scroll +100 +0
Key Up A S Scroll +0 -100
Key Down A S Scroll +0 +100
# Ctrl + Arrow | Scrolls by 1/10 of a page.
Key Left A C Scroll -10 +0
Key Right A C Scroll +10 +0
Key Up A C Scroll +0 -10
Key Down A C Scroll +0 +10
# Ctrl-Super + Arrow | Moves the pointer by 1% of a page.
Key Left A C4 CursorMove -1 0
Key Right A C4 CursorMove +1 +0
Key Up A C4 CursorMove +0 -1
Key Down A C4 CursorMove +0 +1
# Ctrl-Alt-Super + Arrow | Moves the pointer by 1/10 of a page.
Key Left A CM4 CursorMove -10 +0
Key Right A CM4 CursorMove +10 +0
Key Up A CM4 CursorMove +0 -10
Key Down A CM4 CursorMove +0 +10
# Shift-Alt + Arrow | Moves windows to different pages
Key Up A MoveToPage +0p -1p
Key Right A SM MoveToPage +1p +0p
Key Left A SM MoveToPage -1p +0p
Key Down A SM MoveToPage +0p +1p
# Ctrl-Shift-Alt + Arrow | Moves window to page, goes to $page focusing $window
Key Up A CSM MoveAndGotoPage +0p -1p
Key Right A CSM MoveAndGotoPage +1p +0p
Key Left A CSM MoveAndGotoPage -1p +0p
Key Down A CSM MoveAndGotoPage +0p +1p
# Super + Arrow | Tiles window to half screen
Key Left A 4 TileLeft
Key Right A 4 TileRight
Key Up A 4 TileTop
Key Down A 4 TileBottom
# Super-Shift + Arrow | Tiles window to screen quarter
Key Up A S4 TileTopLeft
Key Left A S4 TileBottomLeft
Key Right A S4 TileTopRight
Key Down A S4 TileBottomRight
# Alt + Tab | Cycles between windows
Key Tab A M Next (CurrentPage, !Iconic, !Shaded, \
AcceptsFocus) CirculateFocus
Key Tab A SM Prev (CurrentPage, !Iconic, !Shaded, \
AcceptsFocus) CirculateFocus
# Alt + t | Cycles between terminal emulators
Key t M ToTerm
# Alt + x | Kills a window
Key x A M Close
# Function Keys bindings
Key F1 A C PickWindow
Key F2 A C Iconify
Key F3 A C Thumbnail
Key F4 A C Max
Key F5 A C VerMax
Key F6 A C HorMax
Key F7 A C TileLeft
Key F8 A C TileRight
Key F9 A C Module FvwmIdent
Key F10 A C Close
Key F11 A C FullScreen
Key F12 A C Restart
# Misc additional bindings
Key f A M Fullscreen
Key m A M Max
Key v A M VerMax
Key b A M HorMax
Key Return I N Deiconify-and-Rearrange
Key Return A M Exec exec $[infostore.terminal]
#--- Script Bindings
# Mod4 + w | Changes root background image
Key w A 4 Exec exec /bin/sh $[FVWM_S]/randombg
# Mod4 + s | Takes a window screenshot
Key s A 4 Screenshot
# Mod4 + r | Renames a window
Key r A 4 Exec exec /bin/sh $[FVWM_S]/title
# Mod4 + c | Exports primary CLIPBOARD content to plain text file
# Also echo the recorded entry to a notification daemon
Key c A 4 Exec exec /bin/sh $[FVWM_S]/savexclip
# Mod4 + k | Changes Keyboard Layout
Key k A 4 Exec exec /bin/sh $[FVWM_S]/changexkbmap
# Mod4 + v | Displays Volume Level
Key v A 4 Exec exec /bin/sh $[FVWM_S]/vol
# Xf86/Fn Keyboard Symbols bindings
# Remember to set SUDO_ASKPASS=/usr/pkg/bin/ssh-askpass for password prompt to work
Key XF86AudioMute A N Exec exec mixerctl -w outputs.master=0,0
Key XF86AudioLowerVolume A N Exec exec mixerctl -w outputs.master-=5,5
Key XF86AudioRaiseVolume A N Exec exec mixerctl -w outputs.master+=5,5
Key XF86AudioPlay A N Exec exec mpc play > /dev/null 2>&1
Key XF86AudioStop A N Exec exec mpc pause > /dev/null 2>&1
Key XF86AudioPrev A N Exec exec mpc prev > /dev/null 2>&1
Key XF86AudioNext A N Exec exec mpc next > /dev/null 2>&1
Key XF86MonBrightnessUp A N Exec exec sudo --askpass sysctl -w \
hw.acpi.acpiout0.brightness=100 > /dev/null 2>&1
Key XF86MonBrightnessDown A N Exec exec sudo --askpass sysctl -w \
hw.acpi.acpiout0.brightness=70 > /dev/null 2>&1
Key XF86WWW A N Exec exec seamonkey
Key XF86Terminal A N Exec exec env ENV=$HOME/.profile xterm
Key XF86Mail A N Exec exec urxvt -e neomutt
Key XF86Sleep A N Exec exec sudo --askpass sysctl -w \
hw.acpi.sleep.state=3 > /dev/null 2>&1
Key XF86LogOff A N Exec exec xlock -name $HOME/.Xresources
Key Print A C Exec exec /bin/sh $[FVWM_S]/dumproot 2>&1
# Application Shortcuts
Key l A 4 Exec exec $[infostore.runcmd]
Key e A 4 Exec exec $[infostore.terminal] -g 108x49 -e vim
Key m A 4 Exec exec $[infostore.terminal] -name mutt -e neomutt
Key f A 4 Exec exec $[infostore.terminal] -name mc -e mc
Key p A 4 Exec exec $[infostore.terminal] -name ncmpc++ -e ncmpcpp
Key u A 4 Exec exec $[infostore.browser]
Key t A 4 Exec exec $[infostore.terminal]
###############
#---- Menus
###############=
# Generate XDGMenu
PipeRead "fvwm-menu-desktop -e"
# Read previously generated XDGMenu
#Read $[FVWM_USERDIR]/.XDGMenu
# Main Menu
AddToMenu RootMenu "Fvwm Menu" Title
+ "&Terminal" Exec exec $[infostore.terminal]
+ "&Launcher" Exec exec $[infostore.runcmd]
+ "&Web &Broswer" Exec exec $[infostore.browser]
+ "&Applications" Popup XDGMenu
+ "" Nop
+ "&Man Pages" Popup FvwmManPages
+ "Fvwm&Console" Module FvwmConsole -terminal $[infostore.terminal]
+ "&Window Ops" Popup Window-Ops
+ "&X11 Session" Popup X11-Session
AddToMenu "Window-Ops"
+ "&Move" Move
+ "&Resize" Resize
+ "&Shade" WindowShade
+ "&TileLeft" TileLeft
+ "&TileRight" TileRight
+ "&Stick" Stick
+ "&Send To" Popup SendToPage
+ "" Nop
+ "&Stays On Top" Pick (CirculateHit) Layer 0 6
+ "&Stays Put" Pick (CirculateHit) Layer 0 4
+ "&Stays On Bottom" Pick (CirculateHit) Layer 0 2
+ "" Nop
+ "&Identify" Module FvwmIdent
+ "" Nop
+ "&Close" Close
+ "&Kill" Destroy
AddToMenu "SendToPage"
+ "Page (0,0)" MoveToPage 0 0
+ "Page (0,1)" MoveToPage 0 1
+ "Page (1,0)" MoveToPage 1 0
+ "Page (1,1)" MoveToPage 1 1
# Fvwm Man Pages (Help) Menu
AddToMenu FvwmManPages "Help" Title
+ "fvwm" ViewManPage fvwm
+ "FvwmAnimate" ViewManPage FvwmAnimate
+ "FvwmAuto" ViewManPage FvwmAuto
+ "FvwmBacker" ViewManPage FvwmBacker
+ "FvwmButtons" ViewManPage FvwmButtons
+ "FvwmCommand" ViewManPage FvwmCommand
+ "FvwmConsole" ViewManPage FvwmConsole
+ "FvwmEvent" ViewManPage FvwmEvent
+ "FvwmIconMan" ViewManPage FvwmIconMan
+ "FvwmIdent" ViewManPage FvwmIdent
+ "FvwmPager" ViewManPage FvwmPager
+ "FvwmPerl" ViewManPage FvwmPerl
+ "FvwmProxy" ViewManPage FvwmProxy
+ "FvwmRearrange" ViewManPage FvwmRearrange
+ "FvwmScript" ViewManPage FvwmScript
+ "" Nop
+ "fvwm-root" ViewManPage fvwm-root
+ "fvwm-menu-desktop" ViewManPage fvwm-menu-desktop
+ "fvwm-menu-directory" ViewManPage fvwm-menu-directory
+ "fvwm-menu-xlock" ViewManPage fvwm-menu-xlock
+ "fvwm-config" ViewManPage fvwm-confi
AddToMenu "X11-Session"
+ "Refresh Screen" Refresh
+ "Restart WM" Restart
+ "Lock Screen" Exec exec xlock -name ~/.Xresources
+ "Exit FVWM" Module FvwmScript FvwmScript-ConfirmQuit
+ "" Nop
+ "Reboot System" Exec exec sudo --askpass reboot
+ "Shutdown System" Exec exec sudo --askpass poweroff
d) $[FVWM_S]
As you should have noticed already,some of the functions invoke either ''/bin/sh'' or the built-in ''PipeRead'' parser to execute some shell scripts from the ~/.fvwm/scripts (AKA ''$[FVWM_S]'') directory.
- autoxrandr
#!/bin/sh
# Automatically configure multiscreen setup
# Grab the list of enabled outputs
OUTPUTS=$(xrandr | \
sed -n 's/^\(^[A-Z0-9-]*\) connected [0-9x]*\(+0+0\)*.*/\1\2/p')
# Example:
# VGA1+0+0
# DVI1
ARGS="--auto"
for output in $OUTPUTS; do
# Use the name of the first output to determine the order we
# should use. Consecutive calls of this script will therefore
# reverse the order.
case "$output:$prevoutput" in
*+0+0:)
DIRECTION=left-of
;;
*:)
DIRECTION=right-of
;;
esac
# Autoconfigure this output
ARGS="$ARGS --output ${output%%+*} --auto"
# And put it at left or at right of the previous output
[ -n "$prevoutput" ] && \
ARGS="$ARGS --output ${output%%+*} --$DIRECTION $prevoutput"
prevoutput=${output%%+*}
done
# Call xrandr
xrandr $ARGS
- batt
#!/bin/sh
CHARGE=$(envstat | grep charge: | sed 's/.*(\(.*\))/\1/')
BATT1=$(echo $CHARGE | awk '{print $1}')
BATT2=$(echo $CHARGE | awk '{print $2}')
if envstat | grep -Eiq 'charging.*true'; then
STATUS=charging
else
STATUS=discharging
fi
notify-send -u low "charge levels" " 1st battery = $BATT1 \n2nd battery = $BATT2" \nSTATUS = $STATUS"
3. changexkbmap
#!/bin/sh
layout=`setxkbmap -query | sed -rn 's/layout.*(..)/\1/p'`
case $layout in
us)
setxkbmap it
pgrep -x dunst >/dev/null && notify-send -i kxkb -u low "[Layout] Italian"
;;
it)
setxkbmap us
pgrep -x dunst >/dev/null && notify-send -i kxkb -u low "[Layout] English"
;;
esac
4. randomgb
#!/bin/sh
walls=$HOME/.fvwm/wallpapers/
image=$(shuffle `find $walls -type f` | tail -1)
# rather use feh if you plan on using wallpapers
# which do not match your screen resolution
fvwm-root --retain-pixmap $image
notify-send -u low "background changed"
5. savexclip
#!/bin/sh
xclip -o | xclip -sel clip
echo $(xclip -o -sel clip) >> ~/.xclip_history
sed -n '/^\s*$/d; G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; \
h; P' -i ~/.xclip_history > /dev/null 2>&1
notify-send -u low "CLIPBOARD:" "'$(xclip -o -sel clip)' saved." &
6. title
#!/bin/sh
set -u
main() {
window_id=`xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | awk {'print $2'}`
title=`xwininfo -id "window_id" | perl -ne 'print $1 if /"(.*)"\s*$/'`
if ! tempfile=`mktemp`
then
echo "Cannot create temporary file" 1>&2
exit 1
fi
echo "$title" > "$tempfile"
popup_window_title="Choose new title in editor, then save and exit..."
xterm -T "$popup_window_title" -n "$popup_window_title" \
-e "${EDITOR:-vi}" "$tempfile"
newtitle=`head -c 1000 "$tempfile"`
xwit -id "$window_id" -name "$newtitle"
}
main "$@"
7. vol
#!/bin/sh
VAR=$(mixerctl -n outputs.master | cut -d , -f 1 | \
awk '{print $1/254*100}' | cut -d . -f 1)
VOL=${VAR}%
notify-send -u low "volume level:" "$VOL"
8. xwd2png
#!/bin/sh
main() {
if [ $# = 0 ]
then
do_files *
else
do_files "$@"
fi
}
do_files() {
local file
for file in "$@"
do
if file "$file" | fgrep -q ": XWD X Window Dump image data,"
then
xwdtopnm < $file | pnmtopng > $file.png
mv $file.png `echo $file | sed 's/\(.*\.\)xwd/\1png/'`
rm $file
fi
done
}
main "$@"
9. dumproot
#!/bin/sh
DIR=$HOME/.fvwm/images
xwd -silent -root | convert xwd:- $DIR/root.$(date +'%Y%M%d%H%m%S').png
notify-send "screenshot saved"
d) autostart script
~/.fvwm/autostart is executed as part of FVWM's ''InitFunction'', so place there any program you want to be started in background upon login. Follows an example:
#!/bin/sh
# lock screen after 15 mins of idleness
xautolock -time 15 \
-locker 'xlock -name $HOME/.Xresources' -notify 10 \
-notifier "notify-send 'XLock' '10s before locking display'" &
# open multiple terminal windows within the same process
pgrep urxvtd 2> /dev/null || urxvtd -q -o -f &
# keep the X clipboard and the cutbuffer in sync
autocutsel &
# run pcmanfm in daemon mod, for device discovery
#pcmanfm -d &
# notify daemon
dunst &
# music player daemon
mpd &
# clock
LC_ALL=C xclock &
#
# Background
#
# xsetroot -grey
# bggen darkcyan darkblue black | xv -8 -quic -root -quit -
# xplanet.sh &
# sh $HOME/.fehbg
e) relevant X11/app-defaults
Let's configure our ~/.Xresources as follows:
! ===== General ====
Xft*dpi: 96
Xft*autohint: 0
Xft*antialias: 1
Xft*hinting: 1
Xft*rgba: rgb
Xft*hintstyle: hintslight
Xft*lcdfilter: lcddefault
*.font: -artwiz-anorexia-medium-r-normal--11-110-75-75-p-90-iso10646-1
*.fontList: -artwiz-anorexia-medium-r-normal--11-110-75-75-p-90-iso10646-1
rofi.font: scientifica Bold 8
! ===== Colors ====
*foreground: #D7D0C7
*background: #151515
!black
! *color0: #AF875F
! *color8: #AF875F
*color0: #101010
*color8: #404040
!red
*color1: #E84F4F
*color9: #D23D3D
!green
*color2: #B8D68C
*color10: #A0CF5D
!yellow
*color3: #E1AA5D
*color11: #F39D21
!blue
*color4: #7DC1CF
*color12: #4E9FB1
!magenta
*color5: #9B64FB
*color13: #8542FF
!cyan
*color6: #6D878D
*color14: #42717B
!white
*color7: #dddddd
*color15: #dddddd
URxvt*borderColor: #151515
URxvt*colorBD: #ffffff
URxvt*cursorColor: #ff8939
URxvt*cursorColor2: #151515
! ===== Cursor ====
Xcursor*theme: OpenZone_Ice_Slim
Xcursor*size 12
! ===== URxvt ====
! general
URxvt*termName: rxvt-unicode-256color
URxvt*name: URxvt
URxvt*title: URxvt
URxvt*geometry: 93x35
URxvt*cursorBlink: true
URxvt*internalBorder: 7
URxvt*externalBorder: 0
URxvt*loginShell: true
URxvt*locale: true
URxvt*utf8: true
URxvt*iso14755: false
URxvt*iso14755_52: false
URxvt*preeditType: Root
URxvt*altSendsEscape: true
URxvt*eightBitInput: false
URxvt*metaSendsEscape: true
URxvt*utmpInhibit: false
URxvt*scrollBar: false
URxvt*scrollstyle: xterm
URxvt*thickness: 10
URxvt*scrollBar_right: true
URxvt*scrollBar_floating: false
URxvt*secondaryScroll: true
URxvt*buffered: true
URxvt*urgentOnBell: true
URxvt*visualBell: true
URxvt*mapAlert: true
URxvt*transparent: false
URxvt*renderFont: false
URxvt*shading: 25
URxvt*fading: 0
URxvt*depth: 32
URxvt*intensityStyles: true
URxvt*secondaryScreen: 1
URxvt*scrollTtyOutput: false
URxvt*scrollWithBuffer: true
URxvt*scrollTtyKeypress: true
URxvt*saveLines: 16384
! copy and paste $XA_CLIPBOARD
URxvt*clipboard.copycmd: xclip -in -sel clip
URxvt*clipboard.pastecmd: xclip -out -sel clip
! fonts
URxvt*font: -artwiz-lime-medium-r-normal--10-110-75-75-m-50-iso10646-1
URxvt*boldFont:
URxvt*italicFont:
! extensions
URxvt*perl-ext-common: default,matcher,clipboard,keyboard-select,url-select,font-size,fullscreen,vtwheel
URxvt*charClass: 33:48,35:48,37:48,43:48,45-47:48,64:48,95:48,126:48
URxvt*url-select.launcher: seamonkey
URxvt*url-select.underline: true
URxvt*url-select.autocopy: true
URxvt*url-select.button: 1
URxvt*matcher.button: 1
URxvt*clipboard.autocopy: true
URxvt.keysym.C-f: searchable-scrollback:start
URxvt*keysym.C-u: perl:url-select:select_next
URxvt*keysym.C-x: perl:clipboard:copy
URxvt*keysym.C-v: perl:clipboard:paste
URxvt*keysym.C-Shift-v: perl:clipboard:paste_escaped
URxvt*keysym.C-Delete: perl:matcher:last
URxvt*keysym.C-Shift-Delete:perl:matcher:list
URxvt*keysym.C-Up: perl:font-size:increase
URxvt*keysym.C-Down: perl:font-size:decrease
URxvt*keysym.C-Shift-Up: perl:font-size:incglobal
URxvt*keysym.C-Shift-Down: perl:font-size:decglobal
URxvt*keysym.C-equal: perl:font-size:reset
URxvt*keysym.C-slash: perl:font-size:show
URxvt*keysym.C-a: perl:keyboard-select:activate
URxvt*keysym.C-s: perl:keyboard-select:search
URxvt*keysym.F11: perl:fullscreen:switch
URxvt*tabbed.new-button: false
URxvt*tabbed.tabbar-fg: 7
URxvt*tabbed.tabbar-bg: 0
URxvt*tabbed.tab-fg: 7
URxvt*tabbed.tab-bg: 5
URxvt*tabbed.tabcmds.1: N|sh
URxvt*tabbed.tabcmds.2: R|root|su -
URxvt*tabbed.tabcmds.3: F|nnn|nnn
URxvt*tabbed.tabcmds.4: E|vi|vi
URxvt*tabbed.tabcmds.5: M|mutt|neomutt
URxvt*tabbed.tabcmds.6: H|htop|htop
URxvt*session: N
! ===== XLock ====
XLock*dpmsoff: on
XLock*description: on
XLock*echokeys: on
XLock*echokey: *
XLock*showfps: on
XLock*program: /usr/games/fortune -s
XLock*mailCmd: /usr/bin/mail -H
XLock*lockdelay: 10
XLock*timeout: 15
XLock*use3d: on
XLock*delta3d: 1.5
XLock*right3d: Blue
XLock*left3d: Red
XLock*boTh3d: Magenta
!XLock*info: "screen is locked"
XLock*mode: fzort
XLock*username: user:
XLock*password: key:
Xlock*icongeometry: 96x96
XLock*enablesaver: on
XLock*wireframe: on
XLock*fontset: -artwiz-snap-normal-r-normal--10-100-75-75-p-90-iso10646-1
XLock*planfontset: -artwiz-edges-medium-r-normal--10-100-75-75-m-50-iso10646-1
XLock*messagefont: -artwiz-edges-medium-r-normal--10-100-75-75-m-50-iso10646-1
! ===== XClock ====
XClock*strftime: %a %d %b %H:%M
XClock*padding: 3
XClock*update: 1
XClock*chime: true
XClock*render: true
XClock*digital: false
XClock*Font: -*-helvetica-medium-r-normal--*-80-*-*-*-*-*-*
XClock*geometry: 128x128-3+3
XClock*borderWidth: 1
XClock*foreground: #d79921
XClock*majorColor: #4E9FB1
XClock*minorColor: #D7D0C7
XClock*hourColor: #D7D0C7
XClock*minuteColor: #D7D0C7
XClock*secondColor: #D7D0C7
f) notification deamon
What follows is a sample config for the dunst notifcation daemon, with colors set to match out fvwm theme
Create a ~/.config/dunst/dunstrc file (as well as the parent directory if non-existent) with the following content:
[urgency_low]
# IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the # and following would be interpreted as a comment.
background = "#151515"
foreground = "#D7C0D7"
frame_color = "#4E9FB1"
timeout = 5
[urgency_normal]
background = "#151515"
foreground = "#D7C0D7"
frame_color = "#E1AA5D"
timeout = 10
[urgency_critical]
background = "#151515"
foreground = "#D7C0D7"
frame_color = "#E84F4F"
timeout = 30
[global]
# Defines color of the frame around the notification window.
frame_color = "#aaaaaa"
# Define a color for the separator.
# possible values are:
# * auto: dunst tries to find a color fitting to the background;
# * foreground: use the same color as the foreground;
# * frame: use the same color as the frame;
# * anything else will be interpreted as a X color.
separator_color = frame
# Paths to default icons.
icon_path = /usr/pkg/share/icons/Sardi-Mono/16/status/:/usr/pkg/share/icons/Sardi-Mono/16/devices/
geometry = "0x0-3-3"
# [{width}]x{height}[+/-{x}+/-{y}]
font = nu 8
# The format of the message. Possible variables are:
# %a appname
# %s summary
# %b body
# %i iconname (including its path)
# %I iconname (without its path)
# %p progress value if set ([ 0%] to [100%]) or nothing
# %n progress value if set without any extra characters
# %% Literal %
# Markup is allowed
format = "%s %p\n%b"
# The spacing between lines. If the height is smaller than the
# font height, it will get raised to the font height.
line_height = 0
frame_width = 1
separator_height = 1
notification_height = 0
padding = 8
horizontal_padding = 10
transparency = 7
# Shrink window if it's smaller than the width.
# Will be ignored if width is 0.
shrink = yes
# Possible values are left, center and right.
alignment = left
# Possible values are start, middle and end.
ellipsize = middle
ignore_newline = no
word_wrap = yes
# Align icons left/right/off
icon_position = left
# Scale larger icons down to this size, set to 0 to disable
max_icon_size = 32
# Which monitor should the notifications be displayed on.
monitor = 0
follow = mouse
# Show how many messages are currently hidden (because of geometry).
indicate_hidden = yes
# Sort messages by urgency.
sort = no
# Don't remove messages, if the user is idle (no mouse or keyboard input)
# for longer than idle_threshold seconds.
# Set to 0 to disable.
# Transient notifications ignore this setting.
idle_threshold = 120
markup = full
# Show age of message if message is older than show_age_threshold
# seconds.
# Set to -1 to disable.
show_age_threshold = 60
# Merge multiple notifications with the same content
stack_duplicates = true
# Hide the count of merged notifications with the same content
hide_duplicate_count = false
# Display indicators for URLs (U) and actions (A).
show_indicators = yes
dmenu = /usr/pkg/bin/dmenu -p dunst:
browser = seamonkey
# Should a notification popped up from history be sticky or timeout
# as if it would normally do.
sticky_history = yes
history_length = 20
# Always run rule-defined scripts,
# even if the notification is suppressed
always_run_script = true
title = Dunst
class = Dunst
startup_notification = false
force_xinerama = false
[shortcuts]
# Available modifiers are ctrl, shift, mod1 (alt)
# mod2, mod3 and mod4 (windows-key).
# Close notification.
close = ctrl+space
# Close all notifications.
close_all = ctrl+shift+space
# Redisplay last message(s).
history = ctrl+grave
# action (dmenu)
context = ctrl+alt+c
g) X init script
Time to write a suitable ''~/.xinitrc'' (or ''~/.xsession'' in case you used XDM).
#!/bin/sh
#
# Environmental variables
#
LC_LANG="en_US.UTF-8"; export LC_LANG
LC_CTYPE="en_US.UTF-8"; export LC_CTYPE
DISPLAY=:0; export DISPLAY
env > $HOME/.env
#
# Source possible system-wide startup scripts
#
if [ -d /etc/X11/xinit/xinitrc.d ]; then
for f in /etc/X11/xinit/xinitrc.d/*; do
[ -x "$f" ] && . "$f"
done
unset f
fi
#
# Set up a user-owned tmp directory with restricted access
#
USER=$(whoami)
GROUP=$(id -ng $USER)
mkdir /tmp/${USER}-runtime
chown $USER:$GROUP /tmp/${USER}-runtime
chmod -R 0700 /tmp/${USER}-runtime
XDG_RUNTIME_DIR=/tmp/${USER}-runtime; export XDG_RUNTIME_DIR
TMPDIR=/tmp/${USER}-runtime; export TMPDIR
#
# Check if ~/.cache is a symbolic link to a directory owned by the user.
# If the link's target is not a directory or does not exist, create a
# directory owned by the user under /tmp, and make ~/.cache a symbolic
# link to it.
#
uid=$(id -u)
if [ -L ~/.cache ]; then
if [ -d ~/.cache ]; then
ownerid=$(stat -L -f %u ~/.cache)
if [ "${ownerid}" != "${uid}" ]; then
recreate_cache=1
fi
else
recreate_cache=1
fi
if [ "${recreate_cache}" = "1" ]; then
user=$(whoami)
unlink ~/.cache
cachedir=$(mktemp -d /tmp/${user}.XXXXXX)
ln -s ${cachedir} ~/.cache
fi
fi
#
# Kill dbus services from a previous session in order to prevent hangs.
#
for s in 15 9; do
for p in dbus-launch /usr/pkg/libexec/gvfsd-fuse; do
pgrep -U ${uid} -q $p && pkill -$s $p
done
done
eval $(dbus-launch --sh-syntax)
#
# X settings
#
setxkbmap -model pc105 -layout "it,us" -option terminate:ctrl_alt_bksp
xset s off
xset +dpms # powersaving
xset dpms 1200 1500 1800 # screen blanking
xset b 0 # muted bell
xset m 55/20 4 # mouse acceleration
xset r rate 250 40 # faster keypresses
xset +fp /usr/pkg/share/fonts/X11/artwiz-aleczapka/ # artwiz fonts
xset +fp /home/vincent/.local/share/fonts/ # user fontpath
xhost +local:root > /dev/null 2>&1 # privileged X server access
#xsetroot -cursor_name top_left_arrow #left pointer as cursor
xsetroot -mod 16 16 -fg steelblue -bg black # grid background
xbrightness 65535 0.96 # software screen brightness
#
# Merge in default system resources and keymaps,
# as well as user-defined ones.
#
userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
sysresources=/etc/X11/xinit/Xresources
sysmodmap=/etc/X11/xinit/Xmodmap
if [ -f $sysresources ]; then
xrdb -merge $sysresources
fi
if [ -f $sysmodmap ]; then
xmodmap $sysmodmap
fi
if [ -f $userresources ]; then
xrdb -merge $userresources
fi
if [ -f $usermodmap ]; then
xmodmap $usermodmap
fi
#
# Start wm
#
exec fvwm3
h) GTK+ Theming
I find that the combination of Simply Circle Blue GTK Dark Envolded, Simply Circles Blue Icons, and OpenZone Cursors Ice Slim gets along well enough with my FVWM theme, making the overall consistency of the UI quite pleasing.
i) OK, but how does it look?
Here's s a screenshot of my desktop as of May 2020
