FVWM3ALL(1)

๐Ÿ’– FVWM3ALL ๐Ÿ’–

fvwm3all โ€” the F? Virtual Window Manager for X11, aka the meta-man page ๐Ÿ‘‘ (and yeah, you're reading the FVWM3ALL(1) one, bestie, we're in the right place โœจ)


๐Ÿฆ‹ OVERVIEW ๐Ÿฆ‹

okay so fvwm3 has so many features that the docs literally had to be split up into a bunch of different sections ๐Ÿ˜ญ like it's giving "the lore is too deep for one page". This man page right here? It's the โœจeverything bagelโœจ โ€” it contains all those sections, and those same sections also live in their own separate manpages:

  • fvwm3commands โ€” the builtin fvwm3commands ๐Ÿ’…
  • fvwm3menus โ€” commands/options relating to fvwm3menus ๐ŸŽ€
  • fvwm3styles โ€” style options for handling windows, menus, etc. ๐ŸŒธ

โœจ SYNOPSIS โœจ

fvwm3 [-c config-command] [-d displayname] [-f config-file] [-o logfile]
[-v]

๐ŸŒˆ DESCRIPTION ๐ŸŒˆ

Fvwm is a window manager for X11 optimised for speed โšก no cap, it's fast.

Fvwm is intended to have a small memory footprint, and it's extremely customizable and extendible ๐Ÿซถ. A large virtual desktop and multiple disjoint desktops can be used separately or together. Here's the tea: the virtual desktop pretends your video screen is actually really quite large, so you can scroll around inside it ๐ŸŒ€. The multiple disjoint desktops pretend there are really several screens to work at โ€” but each screen is completely unrelated to the others, like they don't even know each other ๐Ÿ’€.

Fvwm provides keyboard accelerators that let you do practically all window manager functions with keyboard shortcuts โ€” moving and resizing windows, operating the menus, all of it โŒจ๏ธโœจ.

And here's the iconic part: Fvwm does not distinguish between configuration and action commands ๐Ÿ‘‘. Configuration commands typically set fonts, colors, menu contents, and key and mouse function bindings, while action commands do things like raising and lowering windows. Fvwm makes no such distinction and allows anything to be changed at any time ๐Ÿ”ฅ. main character energy fr fr.


โœจ OPTIONS โœจ

okay bestie, these are the command line options that fvwm actually recognizes. buckle up, there's a lot ๐Ÿ’…

  • -i, --clientid id โ€” this one is for when fvwm gets started by a session manager. if you're just a regular person, do NOT touch this one. it's not for you, it's not for me, it's for the session manager.
  • -c, --cmd config-command โ€” makes fvwm use config-command instead of Read config (or Read .fvwm2rc) as its initialization command. (btw, up to 10 -f and -c parameters can be given, and they run in the order you specified them. yes, order matters, periodt.)

any module started by command line arguments is assumed to be a module that sends back config commands. all command line modules have to quit before fvwm proceeds on to the StartFunction and setting border decorations and styles. there's a potential deadlock if you start a module other than FvwmPerl, but there's a timeout so fvwm eventually gets going. ๐Ÿ˜ฎโ€๐Ÿ’จ

as an example, starting the pager this way hangs fvwm until the timeout, but the following should work well:

fvwm -c "AddToFunc StartFunction I Module FvwmPager"
  • -d, --display displayname โ€” manage the display called displayname instead of whatever name it got from the environment variable $DISPLAY. iconic, honestly.
  • -f config-file โ€” makes fvwm read config-file instead of ~/.fvwm/config as its initialization file. $FVWM_USERDIR can also be used to change the location of the default user directory ~/.fvwm. ๐Ÿซถ
  • -o logfile โ€” write log messages to logfile. if logfile is -, log to the console. (this does not turn on logging, see the -v option. i know, sneaky.)
  • -h, --help โ€” a short usage description gets printed. the bare minimum, and honestly? valid.
  • -r, --replace โ€” try to take over from a previously running wm. this does not work unless the other wm is ICCCM2 2.0 compliant. so like, vibe check the other wm first.
  • -F, --restore state-file โ€” this option is used when fvwm is started by a session manager. should not be used by a user. again bestie, not for us.
  • -V, --version โ€” prints the version of fvwm to stderr. also prints info about the compiled-in features as stated at compiletime. cute little flex tbh โœจ
  • -C, --visual visual-class โ€” makes fvwm use visual-class for the window borders and menus. visual-class can be "StaticGray", "GrayScale", "StaticColor", "PseudoColor", "TrueColor" or "DirectColor". six choices, all valid, no wrong answers.
  • -I, --visualid id โ€” makes fvwm use id as the visual id for the window borders and menus. id can be specified as N for decimal or 0xN for hexadecimal. see the man page of xdpyinfo for a list of supported visuals. iykyk.
  • -l, --color-limit limit โ€” specifies a limit on the colors used in image, gradient and possibly simple colors used by fvwm. in fact, fvwm (and all the modules) uses a palette with at most limit colors. this option is only useful with screens that display 256 colors (or less) with a dynamic visual (PseudoColor, GrayScale or DirectColor). the default depends on your X server and how you run fvwm. in most cases this default is reasonable. the -l option should be used only if you encounter problems with colors. by default, fvwm tries to detect large pre-allocated palettes. if such a palette is detected fvwm uses it and a priori the -l must not be used. moreover, in this case the -A and -S options are forced. note that XFree-4.2 pre-allocates 244 colors (if you use a driver with Render support) leaving only a few free colors. this may lead to some color problems (and nothing can be done ๐Ÿ˜ญ). XFree-4.3 or better pre-allocate only 85 colors. if no pre-allocated palette is auto detected the defaults are as follow:

Display depth 8 (256 colors)

  • PseudoColor: 68 (4x4x4 color cube + 4 grey)
  • GrayScale: 64 regular grey
  • DirectColor: 32 (3x3x3 color cube + 5 grey)

Display depth 4 (16 colors)

  • PseudoColor: 10 (2x2x2 color cube + 2 grey)
  • GrayScale: 8 regular grey
  • DirectColor: 10 (2x2x2 color cube + 2 grey)

note that if you use a private color map (i.e., fvwm is started with the -C or the -I options), then other defaults are used.

now what to do if you encounter problems with colors? the first thing to do is to check if you really cannot run your X server with depth 15, 16 or better. check your X server documentation. note that some hardware can support two different depths on the same screen (typically depth 8 and depth 24). if depth 8 is the default, you can force fvwm to use the best depth by using the -C option with TrueColor as argument. so now we assume that you are forced to run in depth 8 with a dynamic visual because your hardware/driver cannot do better or because you need to use an application which needs to run under this mode (e.g., because this application needs read-write colors). what it should be understood is that you have only 256 colors and that all the applications which use the default color map must share these colors. the main problem is that there are applications which use a lot or even all the colors. if you use such application you may have no more free colors and some applications (which used only a few colors) may fail to start or are unusable. there are three things that can be done (and fvwm does not really play a particular role, all applications are concerned). the first is to run the applications which waste your (default) color map with a private color map. for example, run netscape with the -install option, run KDE or QT applications with the --cmap option, use the -C option for fvwm. the disadvantage of this method is that it is visually disturbing (see the ColormapFocus command for a better control of the color maps switching). the second method is to limit the number of colors that the applications use. again, some applications have options to specify a given color limit. with fvwm you may try various values, 61 (a special "visual" palette), 56 (a 4x4x3 color cube plus 6 grey), 29 (a 3x3x3 color cube plus 2 grey), 10 or 9. also, you may use the -L option. however, limiting the number of colors is not the definitive solution. the definitive solution is to try cause applications which use a lot of colors use the same colors. this is a difficult task as there are no formal standards for this goal. however, some toolkits as QT and GTK use color cubes as palettes. so, the idea is to configure your applications/toolkits to all use the same color cube. moreover, you can use the colors in this color cube in your X resources configuration files and/or as arguments to colors options. Fvwm can use any color cube of the form RxGxB with 2 <= R <= 6, R = G, R-1 =< B <= R and B >= 2. to get an RxGxB color cube give an argument to -l an integer c >= R*G*B and < (R+1)(G+1)*B if B=R and < R*G(B+1) if B < R (and different from 61). if c > R*G*B, then some grey may be added to the color cube. you can use the PrintInfo Colors [1] command to get information on your fvwm colors setting. in particular, this command prints the palette used by fvwm in rgb format (the last integer gives the number of times fvwm has allocated the colors). that was a whole essay but we got through it together bestie ๐Ÿ’–

  • -L, --strict-color-limit โ€” if the screen displays 256 colors (or less) and has a dynamic visual, causes fvwm to use its palette for all the colors. by default, the palette is used only for images and gradients.
  • -P, --visual-palette โ€” if the screen displays 256 colors (or less) and has a dynamic visual, this option causes fvwm to use a palette designed for limiting the "visual" color distance between the points of the palette. moreover, for better color sharing, if possible colors with a name in the X rgb data base are used for defining the colors (with the hope that applications and images prefer to use named colors). if the -l option is not used this palette has 61 colors. this palette is also automatically selected if 61 or 9 is used as argument to the -l option.
  • -A, --allocate-palette โ€” if the screen displays 256 colors (or less) and has a dynamic visual this option causes fvwm to allocate all the colors of its palette at start up for reserving these colors for future use. this option forces the -static-palette option. by default, fvwm allocates (reserves) a color in its palette only if it needs this color.
  • -S, --static-palette โ€” if the screen displays 256 colors (or less) and has a dynamic visual this option causes fvwm to never free the colors in its palette. by default, when fvwm does not need a color any more it frees this color so that a new color can be used. this option may speed up image loading and save a few bits of memory. little win, still a win โœจ
  • --debug-stack-ring โ€” enables stack ring debugging. this option is only intended for internal debugging and should only be used by developers. not us. hands off bestie ๐Ÿ™ˆ
  • -v, --verbose โ€” enables debug logging. writes in append mode to fvwm log file, which is ~/.fvwm/fvwm3-output.log by default. see the ENVIRONMENT section on how to override this location on fvwm3 startup using $FVWM_USERDIR or $FVWM3_LOGFILE.

logging can also be dynamically toggled on and off using signals:

SIGUSR1 : used as a signal to restart Fvwm
SIGUSR2 : used as a signal to toggle opening/closing debug log file

๐ŸชŸ ANATOMY OF A WINDOW ๐ŸชŸ

Fvwm puts a decorative border around most windows. this border consists of a bar on each side and a small L-shaped section on each corner. there is an additional top bar called the title-bar which is used to display the name of the window. in addition, there are up to 10 title-bar buttons. the top, side, and bottom bars are collectively known as the side-bars. the corner pieces are called the frame. okay so it's giving very much window couture ๐Ÿ’…

with the built-in minimal configuration, dragging mouse button 1 in the frame or side-bars begins a resize operation on the window. dragging mouse button 2 in the frame or side-bars begins a move operation. there are raise/lower operations bound to a single clicking on borders. similarly for the window title.

up to ten title-bar buttons may exist. their use is completely user definable. one popular configuration uses one button on the left that is used to bring up a list of window options and two buttons on the right used to iconify and maximize the window. another popular configuration adds a close button to the right. the number of title-bar buttons used depends on which ones have mouse actions bound to them. see the Mouse command. the customization potential is honestly unmatched, main character energy fr fr ๐Ÿ‘‘

๐Ÿ–ฅ๏ธ THE VIRTUAL DESKTOP ๐Ÿ’–

okay bestie, listen โ€” fvwm gives you multiple virtual desktops if you're the kind of person who wants them (and you are, you're here). The screen is basically a viewport looking onto a desktop that can be bigger than the screen itself. You can have several totally distinct desktops (the whole idea: one desktop per project, or one desktop per app when the apps are all separate vibes). And since each desktop can be larger than the physical screen, it gets chopped into m by n pages, each one exactly the size of your physical screen โ€” so windows bigger than your screen, or big clumps of related windows, are super easy to look at. slay. ๐Ÿซถ

The (m by n) size of the virtual desktops โ€” that's the number of pages, bestie โ€” can be changed any time with the DesktopSize command. All virtual desktops have to be (and are) the same size. You don't have to specify the total number of distinct desktops, and it's limited to roughly 4 billion total, which is lowkey more than you'll ever need ๐Ÿ’…. All the windows across a range of desktops can be seen in the FvwmPager, which is a lil miniature view of your desktops. The pager is an accessory program โ€” a module โ€” and it is not essential for the window manager to operate, it's just cute. Windows can also be listed with the WindowList command or the FvwmIconMan module. โœจ

Fvwm keeps the windows on your desktop in a layered stacking order, and this is the rule that matters: a window in a lower layer never obscures a window in a higher layer. periodt. You can change a window's layer with the Layer command. The whole layer concept is a generalization of the StaysOnTop flag from older fvwm versions โ€” the StaysOnTop and StaysPut Style options are now implemented by putting windows in suitable layers, and the previously missing StaysOnBottom Style option got added too. glow up ๐Ÿ’–

Sticky windows are windows that transcend the virtual desktop by literally "Sticking to the screen's glass". They always stay put on the screen, no matter what. This is so convenient for things like clocks and xbiffs โ€” you only need to run one such gadget and it always stays with you. Icons can also be made to stick to the glass, if you want that. ๐ŸŽ€

Window geometries are specified relative to the current viewport. That is:

xterm -geometry +0+0

creates a window in the upper left hand corner of the visible portion of the screen. And yes, you're allowed to specify geometries that place windows on the virtual desktop but off the screen โ€” living your off-screen main character era. For example, if the visible screen is 1000 by 1000 pixels, and the desktop size is 3x3, and the current viewport is at the upper left hand corner of the desktop, invoking:

xterm -geometry +1000+1000

places a window just off of the lower right hand corner of the screen. You can find it by moving the mouse to the lower right hand corner of the screen and waiting for it to scroll into view. A geometry specified as something like:

xterm -geometry -5-5

places the window's lower right hand corner 5 pixels from the lower right corner of the visible portion of the screen. Heads up though: not all applications support window geometries with negative offsets. Some applications place the window's upper right hand corner 5 pixels above and to the left of the upper left hand corner of the screen; others may do just plain bizarre things. ๐Ÿ˜ญ not their fault, it's giving undefined behaviour.

There's a fvwm-specific extension to geometry strings which can also enforce that the geometry is relative to the given screen. For example:

xterm -geometry +0+0@n

Where n can be one of a RandR monitor name, or an assigned monitor number. For more details, see the RANDR SUPPORT section. ๐Ÿ‘‘

There are several ways to cause a window to map onto a desktop or page other than the currently active one. The geometry technique mentioned above (specifying x,y coordinates larger than the physical screen size) however suffers from the limitation of being interpreted relative to the current viewport: the window may not consistently appear on a specific page, unless you always invoke the application from the same page. annoying, ik.

A better way to place windows on a different page, screen or desk from the currently mapped viewport is to use the StartsOnPage or StartsOnScreen style specification (the successors to the older StartsOnDesk style) in your config file. The placement is consistent: it does not depend on your current location on the virtual desktop. ate. โœจ

Some applications that understand standard Xt command line arguments and X resources โ€” like xterm and xfontsel โ€” let you specify the start-up desk or page right on the command line:

xterm -xrm "*Desk:1"

starts an xterm on desk number 1;

xterm -xrm "*Page:3 2 1"

starts an xterm two pages to the right and one down from the upper left hand page of desk number 3. Not all applications understand the use of these options, however. You could achieve the same results with the following lines in your .Xdefaults file:

XTerm*Desk: 1

or

XTerm*Page: 3 2 1

๐ŸŒˆ RANDR MULTI-SCREEN SUPPORT ๐Ÿ–ฅ๏ธ๐Ÿ–ฅ๏ธ

Fvwm best supports multiple screens using the RandR X11 protocol. If fvwm isn't built with the RandR protocol then the multi screen support is very limited, and it is suggested to rebuild with RandR. It's also recommended to use EdgeScroll 0 0 on multi-screen displays to avoid changing pages when moving the mouse between screens. ๐Ÿ’…

If Fvwm has been compiled with RandR support then it tracks the outputs (displays) which it finds. These outputs are stored by name, which can be found by running the xrandr(1) command.

When Fvwm detects monitors, it adds them to a tree with a defined order, and each monitor gets assigned a number. That order is top-down, left-to-right, so for example, the following diagram illustrates a monitor layout and their assigned number. ๐Ÿ‘‘

    A (0)
    B (1)   C (2)    D (3)

Hence it's possible to refer to the 2nd monitor and print its name via expansion variables as:

$[monitor.1.name]

Which would print the name, B. (yes, 1 is the second one, we count from zero around here, it's giving programmer) ๐Ÿ˜Œ

In doing so, Fvwm tracks events from RandR, such as when a given output changes size, or has been added or removed.

These are controlled by FvwmEvent. ๐Ÿฆ‹


๐ŸŽ€ DESKTOP BEHAVIOUR ๐Ÿ’–

Because Fvwm has the capability to track outputs, Fvwm can be told how to handle those. This is controlled via the DesktopConfiguration command. By default, Fvwm treats all the outputs it finds as one large screen, although Fvwm can be told to treat screens independently of each other. your call bestie โœจ


๐Ÿš€ INITIALIZATION ๐ŸŒธ

During initialization, fvwm searches for a configuration file which describes key and button bindings, and many other things. The format of these files is described later. Fvwm first searches for configuration files using the command

Read config

This looks for file config in $FVWM_USERDIR and $FVWM_DATADIR directories, as described in Read. If this fails, more files are queried for backward compatibility. Here's the complete list of all file locations queried in the default installation (only the first found file is used):

$HOME/.fvwm/config
/usr/local/share/fvwm/config

$HOME/.fvwm/.fvwm2rc
$HOME/.fvwm2rc
/usr/local/share/fvwm/.fvwm2rc
/usr/local/share/fvwm/system.fvwm2rc
/etc/system.fvwm2rc
Please note, the last 5 locations are not guaranteed to be supported in the future. ๐Ÿ™ˆ so don't get too attached.

If a configuration file is not found, the left mouse button, or

or

keys on the root window bring up menus and forms that can create a starting configuration file.

Fvwm sets two environment variables which are inherited by its children. These are:

  • $DISPLAY โ€” describes the display on which fvwm is running. $DISPLAY may be unix:0.0 or :0.0, which doesn't work too well when passed through ssh to another machine.
  • $HOSTDISPLAY โ€” set to a network-ready description of the display. $HOSTDISPLAY always uses the TCP/IP transport protocol (even for a local connection) so $DISPLAY should be used for local connections, as it may use Unix-domain sockets, which are faster. ๐Ÿƒโ™€๏ธ๐Ÿ’จ

If you want to start some applications or modules with fvwm, you can simply put

Exec app

or

Module FvwmXxx

into your config, but it is not recommended; do this only if you know what you are doing. It is usually important to start applications or modules after the entire config is read, because it contains styles or module configurations which can affect window appearance and functionality. ๐Ÿ‘‘

The standard way to start applications or modules on fvwm's start up is to add them to an initialization function (usually StartFunction or InitFunction). This way they're only started after fvwm finishes reading and executing the config file. โœจ

Fvwm has three special functions for initialization:

  • StartFunction โ€” executed on startups and restarts.
  • InitFunction and RestartFunction โ€” executed during initialization and restarts (respectively) just after StartFunction.

These functions may be customized in a user's config file using the AddToFunc command (described later) to start up modules, xterms, or whatever you'd like to have started by fvwm. ๐ŸŽ€

Fvwm has also a special exit function: ExitFunction, executed when exiting or restarting before actually quitting. It could be used to explicitly kill modules, etc.

If fvwm is run under a session manager, functions SessionInitFunction and SessionRestartFunction are executed instead of InitFunction and RestartFunction. This helps to define the user's config file to be good for both running under a session manager and without it. Generally it is a bad idea to start xterms or other applications in "Session*" functions. Also someone can decide to start different modules while running under a session manager or not. For similar purposes SessionExitFunction is used instead of ExitFunction.

DestroyFunc StartFunction
AddToFunc StartFunction
 + I Module FvwmPager * *
 + I Module FvwmButtons

DestroyFunc InitFunction
AddToFunc InitFunction
 + I Module FvwmBanner
 + I Module FvwmIconMan
 + I Exec xsetroot -solid cyan
 + I Exec xterm
 + I Exec netscape

DestroyFunc RestartFunction
AddToFunc RestartFunction
 + I Module FvwmIconMan

DestroyFunc SessionInitFunction
AddToFunc SessionInitFunction
 + I Module FvwmBanner

DestroyFunc SessionRestartFunction
AddToFunc SessionRestartFunction
 + I Nop

You do not need to define all special functions if some are empty. Also note, all these special functions may be emulated now using StartFunction and ExitFunction, like this:

DestroyFunc StartFunction
AddToFunc StartFunction
+ I Test (Init) Module FvwmBanner
+ I Module FvwmPager * *
+ I Test (Restart) Beep

DestroyFunc ExitFunction
AddToFunc ExitFunction
+ I Test (Quit) Echo Bye-bye
+ I KillModule MyBuggyModule
+ I Test (ToRestart) Beep

๐Ÿ› ๏ธ COMPILATION OPTIONS ๐Ÿ› ๏ธ

Okay so real talk: fvwm has a whole bunch of compile-time options, and if some command or feature is acting brand new and refusing to work, bestie, go check whether support for it was even compiled in. ๐Ÿ’… The optional features are all described in the config.h file that gets generated when you compile.


๐ŸŒˆ ICONS AND IMAGES ๐ŸŒˆ

So fvwm can load .xbm, .xpm, .png and .svg images. Let's break that down:

  • XBM โ€” monochrome, and fvwm can always display these, no cap.
  • XPM and PNG โ€” color images, slay.
  • SVG โ€” vector graphics image format, very main character.

Whether fvwm can actually display XPM, PNG or SVG icons and images depends on those compile-time options we just talked about. Peep the INSTALL.fvwm file for the tea. โ˜•

There's also a related SHAPE compile-time option that can make fvwm display spiffy shaped icons. โœจ

๐ŸŽจ SVG rendering options ๐ŸŽจ

SVG images get generated from (XML) text files. A really simple SVG file might look something like this:

<svg width="120" height="80">
<rect fill="red"     width="40" height="40"  x="0"   y="0"  />
<rect fill="lime"    width="40" height="40"  x="40"  y="0"  />
<rect fill="blue"    width="40" height="40"  x="80"  y="0"  />
<rect fill="cyan"    width="40" height="40"  x="0"   y="40" />
<rect fill="magenta" width="40" height="40"  x="40"  y="40" />
<rect fill="yellow"  width="40" height="40"  x="80"  y="40" />
</svg>

By default, SVG images are rendered exactly the way the image creator intended them to be. But like โ€” SVG is a vector graphics format, so the images can be rendered at any chosen size and rotation, which means you can use the same icon file rendered at different sizes for the Icon and MiniIcon styles. Obsessed, honestly. ๐Ÿฆ‹

The rendering options are specified as a string appended to the SVG filename, like this:

_image.svg_:[!] [(1) _size_] [(2) _position_] [(3) _rotation_] [(4)
_scale_] ...

{empty}(1) [-]_width_{x}[-]_height_

{empty}(2) {- | +}_xpos_{- | +}_ypos_

{empty}(3) @[-]_angle_

{empty}(4) {* | }[-]_factor_[x | y]

The option string always starts with a colon (':') to separate it from the filename. An empty option string can skip this colon, but honestly it might still be a good idea to include it, so there's no ambiguity if the filename contains any colon. ๐Ÿ”

filename_without_colon.svg
filename:with:colon.svg:

An exclamation point ('!') transposes the entire final image (including the rendering area), i.e. all the horizontal and all the vertical coordinates get swapped with each other.

image.svg:!

width and height specify the dimensions of the rendering area in pixels โ€” that's the dimensions of the resulting image. The actual image is fitted to fill the entire rendering area.

image.svg:60x60

Use a width or height value of 0 to keep the aspect ratio. ๐Ÿซถ

image.svg:0x60
image.svg:60x0

A '-' before width mirrors the rendering area horizontally.

image.svg:-0x0

A '-' before height mirrors the rendering area vertically.

image.svg:0x-0

xpos and ypos specify a translation of the image in pixels. A positive xpos value moves the image to the right. A positive ypos value moves it down. Moving it partially outside of the rendering area results in a cropped image. ๐Ÿ˜ญ

image.svg:-30-0
image.svg:-0+10
image.svg:-30+10

angle specifies a rotation around the actual image center in degrees. This might result in a cropped image. A positive value rotates the image clockwise. Floating point values are recognized.

image.svg:@180
image.svg:@-90
image.svg:@30
image.svg:@57.3

factor specifies a scaling of the actual image (not the rendering area). Scaling it up results in a cropped image. Floating point values are recognized. Division by zero is ignored. If factor is directly followed by a 'x' or a 'y', the scaling is horizontal or vertical respectively. Otherwise the scaling is uniform.

image.svg:*2
image.svg:/2
image.svg:/3x
image.svg:/2y

Scaling down a translated or rotated image can prevent cropping. ๐Ÿ’ก

image.svg:@30*0.6

Repeated usage of translation, rotation, and scaling is allowed. Translation and rotation are additive. Scaling is multiplicative.

image.svg:*2/3
image.svg:/3x/2y

When combining affine transformations, the scaling is always done first, then the rotation, and finally the translation.

image.svg:-30+10@30/3x/2y

Use a negative scale factor to mirror the actual image.

image.svg:-30+10@30/-3x/2y

Mirroring of the rendering area is done after any scaling, rotation or translation of the image.

image.svg:-0x0-30+10@30/3x/2y

Transposing is done last of all, after everything else.

image.svg:!-0x0-30+10@30/3x/2y

๐Ÿงฉ MODULES ๐Ÿงฉ

A module is a separate program that runs as a separate Unix process but transmits commands to fvwm to execute. Users can write their own modules to do any weird or bizarre manipulations without bloating or affecting the integrity of fvwm itself. Iconic behaviour, no notes. ๐Ÿ‘‘

Modules must be spawned by fvwm so that it can set up two pipes for fvwm and the module to communicate with. Those pipes are already open for the module when it starts, and the file descriptors for the pipes are provided as command line arguments.

Modules can be spawned by fvwm at any time during the X session by use of the Module command. Modules can exist for the duration of the X session, or can perform a single task and exit. If the module is still active when fvwm is told to quit, then fvwm closes the communication pipes and waits to receive a SIGCHLD from the module, indicating that it has detected the pipe closure and has exited. If modules fail to detect the pipe closure, fvwm exits after approximately 30 seconds anyway. โณ The number of simultaneously executing modules is limited by the operating system's maximum number of simultaneously open files, usually between 60 and 256.

Modules simply transmit commands to the fvwm command engine. Commands are formatted just as in the case of a mouse binding in the config setup file. Certain auxiliary information is also transmitted, as in the sample module FvwmButtons.

Please refer to the Module Commands section for details. ๐Ÿ‘€


๐Ÿ“œ ICCCM COMPLIANCE ๐Ÿ“œ

Fvwm attempts to be ICCCM 2.0 compliant. Check http://tronche.com/gui/x/icccm/ for more info. In addition, ICCCM states that it should be possible for applications to receive any keystroke โ€” which is genuinely not consistent with the keyboard shortcut approach used in fvwm and most other window managers. In particular, you cannot have the same keyboard shortcuts working with your fvwm and another fvwm running within Xnest (a nested X server running in a window). The same problem exists with mouse bindings. ๐Ÿ™ˆ

The ICCCM states that windows possessing the property

WM_HINTS(WM_HINTS):
Client accepts input or input focus: False

should not be given the keyboard input focus by the window manager. These windows can take the input focus by themselves, however. A number of applications set this property and yet expect the window manager to give them the keyboard focus anyway, so fvwm provides a window style, Lenience, which allows fvwm to overlook this ICCCM rule. Even with this window style, it is not guaranteed that the application accepts focus.

The differences between ICCCM 1.1 and 2.0 include the ability to take over from a running ICCCM 2.0 compliant window manager; thus

fvwm; vi ~/.fvwm/config; fvwm -replace

resembles the Restart command. It is not exactly the same, since killing the previously running wm may terminate your X session, if the wm was started as the last client in your .Xclients or .Xsession file. โš ๏ธ

Yeah bestie, be careful with that one. It's giving "oops I killed my whole session." ๐Ÿ’€

Further additions are support for client-side colormap installation (see the ICCCM for details) and the urgency hint. Clients can set this hint in the WM_HINTS property of their window and expect the window manager to attract the user's attention to the window. Fvwm has two re-definable functions for this purpose, "UrgencyFunc" and "UrgencyDoneFunc", which are executed when the flag is set/cleared. Their default definitions are:

AddToFunc UrgencyFunc
 + I Iconify off
 + I FlipFocus
 + I Raise
 + I WarpToWindow !raise 5p 5p
AddToFunc UrgencyDoneFunc
 + I Nop

๐Ÿ”ฅ EXTENDED WINDOW MANAGER HINTS ๐Ÿ”ฅ

Fvwm attempts to respect the extended window manager hints (ewmh or EWMH for short) specification: https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html and some extensions of this specification.

This support is configurable with styles and commands. These styles and commands have EWMH as the prefix (so you can find them easily in this man page). ๐Ÿ”Ž

There is a new Context 'D' for the Key, PointerKey, Mouse commands. This context is for desktop applications (such as kdesktop and Nautilus desktop).

When a compliant taskbar asks fvwm to activate a window (typically when you click on a button which represents a window in such a taskbar), then fvwm calls the complex function EWMHActivateWindowFunc which by default is Iconify Off, Focus and Raise. You can redefine this function. For example:

DestroyFunc EWMHActivateWindowFunc
AddToFunc EWMHActivateWindowFunc I Iconify Off
+ I Focus
+ I Raise
+ I WarpToWindow 50 50

additionally warps the pointer to the center of the window. ๐ŸŽฏ

The EWMH specification introduces the notion of Working Area. Without ewmh support the Working Area is the full visible screen (or all your screens if you have a multi head setup with RandR). However, compliant applications (such as a panel) can ask to reserve space at the edge of the screen. If this is the case, the Working Area is your full visible screen minus these reserved spaces. If a panel can be hidden by clicking on a button, the Working Area does not change (as you can unhide the panel at any time), but the Dynamic Working Area is updated: the space reserved by the panel is removed (and added again if you pop up the panel). The Dynamic Working Area may be used when fvwm places or maximizes a window. To know if an application reserves space you can type "xprop | grep _NET_WM_STRUT" in a terminal and select the application. If four numbers appear then these numbers define the reserved space as explained in the EwmhBaseStruts command. ๐ŸŒธ

๐ŸŒธ CONFIGURATION ๐ŸŒธ

๐Ÿ’– Configuration Files ๐Ÿ’–

So bestie, the config file is literally where you tell fvwm what to be. It's the place you describe your mouse and button bindings, your colors, the size of your virtual display, and all the other related little things that make your setup yours. The initialization configuration file is typically called config โ€” or .fvwm2rc, if you're feeling nostalgic ๐Ÿซถ. And here's the slay part: by using the Read command, you can read in new configuration files as you go, no restart required. Obsessed.

Some ground rules for what goes in there, and they're giving very much shell-script energy:

  • Lines beginning with # are ignored by fvwm. They're just for you, bestie. Comment away ๐Ÿ’…
  • Lines starting with * are expected to contain module configuration commands (rather than configuration commands for fvwm itself). iykyk.
  • Like in shell scripts, embedded newlines in a configuration file line can be quoted by preceding them with a backslash. All lines linked in this fashion are treated as a single line, and the newline itself is ignored. So you can break a long line without breaking the vibe โœจ

And the big one: fvwm makes no distinction between configuration commands and action commands. Ngl, that's kind of iconic. Anything mentioned in the fvwm commands section can be placed on a line by itself for fvwm to execute as it reads the configuration file, or it can be placed as an executable command in a menu, or bound to a mouse button or a keyboard key. Same energy either way. It is left as an exercise for the user to decide which functions make sense for initialization and which ones make sense for run-time ๐Ÿ™ˆ โ€” yes, that's genuinely up to you, bestie, go off.


๐ŸŽ€ Supplied Configuration ๐ŸŽ€

A sample configuration file is supplied with the fvwm distribution. It is well commented and can be used as a source of examples for fvwm configuration โ€” lowkey a whole tutorial in a file. It may be copied from /usr/local/share/fvwm/config.

Alternatively, the built-in menu (accessible when no configuration file is found) has options to create an initial config file for the user. So if you show up with nothing, fvwm's like "don't worry bestie, I got you" ๐Ÿ’–

โœจ FONTS โœจ

okay bestie, this is the section where we talk about the lettering ๐Ÿ’… โ€” all the text that shows up on your window titles, icon titles, menus and the geometry window. You set that up with the Font and IconFont styles, the Font MenuStyle, and the DefaultFont command. And literally every Module that draws text has its own config command(s) for picking a font too. All of these take a font name as their argument. So the big question: what even is a font name for fvwm, and which fonts does it actually load? Let's get into it ๐Ÿซถ


๐ŸŒธ Font names and font loading ๐ŸŒธ

First up, the classic. You can hand fvwm what we'll call a usual font name, like:

-adobe-courier-bold-r-normal--10-100-75-75-m-60-ISO8859-1
-adobe-courier-bold-r-normal--10-*
-*-fixed-medium-o-normal--14-*-ISO8859-15

That's an X Logical Font Description โ€” XLFD for short, iykyk. fvwm loads the "first" font that matches your description, and which one counts as "first" depends on your font path and your locale. Fonts that match your locale charset get loaded in priority order. So if you ask for

-adobe-courier-bold-r-normal--10-*

and your locale charset is ISO8859-1, fvwm goes hunting for a font matching

-adobe-courier-bold-r-normal--10-*-ISO8859-1

and if your locale charset is ISO8859-15 instead, it goes for

-adobe-courier-bold-r-normal--10-*-ISO8859-15.

โœจ You can also drop an extended XLFD, which is just a comma separated list of (simple) XLFD font names, like:

-adobe-courier-bold-r-normal--14-*,-*-courier-medium-r-normal--14-*

Each simple font name gets tried until a matching font with the locale charset shows up, and if that fails, each simple font name gets tried again without any constraint on the charset. no font left behind ๐Ÿ’ช

Wanna go deeper on the XLFD? Peep the X manual page, the X Logical Font Description Conventions document (called xlfd) and the XLoadFont and XCreateFontSet manual pages. Handy font utilities to have in your toolkit: xlsfonts, xfontsel, xfd and xset. ๐ŸŒˆ

Now โ€” if you have Xft support, you can specify an Xft font name (a description, technically) of a true type (or Type1) font, prefixed with "xft:". Like:

"xft:Luxi Mono"
"xft:Luxi Mono:Medium:Roman:size=14:encoding=iso8859-1"

Again, the "first" font matching the description is the one that loads. Which one is "first" depends on the XftConfig configuration file with Xft1, and on the /etc/fonts/fonts.conf file with Xft2. You can read the Xft manual page, and with Xft2, the fontconfig man page too. ๐Ÿ‘‘

So how do you read these? The first string after "xft:" is always the family. In the second example, Luxi Mono is the Family (other XFree TTF families out there: "Luxi Serif", "Luxi Sans"), Medium is the Weight (other possible weights: Light, DemiBold, Bold, Black), Roman is the slant or the style (other possibilities: Regular, Oblique, Italic), size sets the point size (want pixel size instead? use pixelsize=), and encoding lets you enforce a charset (iso8859-1 or iso10646-1 only โ€” if you don't give an encoding, the locale charset is assumed).

One super important parameter is "minspace=bool" where bool is True or False. If bool is False (the default? ๐Ÿค”) Xft gives fvwm a greater font height than if bool is True. And that can shift text placement, icon and window title height, line spacing in menus and FvwmIdent, button height in some fvwm modules ...etc. If you're on an LCD monitor, try adding "rgba=mode" where mode is either rgb, bgr, vrgb or vbgr to turn on subpixel rendering โ€” the best mode depends on how your LCD cells are arranged, so vibe-check it yourself. You can also pass other specs in between the ":", like "foundry=foundry_name", "spacing=type" where type can be monospace, proportional or charcell, "charwidth=integer", "charheight=integer" or "antialias=bool" where bool is True or False. Ngl it seems like these parameters aren't always taken into account. ๐Ÿ™ˆ

Want to find out which Xft fonts are actually getting loaded? Export XFT_DEBUG=1 before starting fvwm and go peek at the error log. With Xft2 you can use fc-list to list the available fonts. Anyway โ€” heads up bestie โ€” Xft support is experimental (from the X and the fvwm point of view), and the quality of the rendering depends on a whole pile of parameters (your XFree and freetype versions and your video card(s)). ๐Ÿ‘€

๐Ÿ’– Here's a cute trick: after an Xft font name, you can add โ€” following a ";" โ€” an XLFD font name (simple or extended), like:

xft:Verdana:pixelsize=14;-adobe-courier-bold-r-normal--14-*

Then, if either loading the Xft font fails or fvwm has no Xft support, fvwm loads the font "-adobe-courier-bold-r-normalโ€”14-*". This is how you write portable configuration files, periodt. ๐ŸŒŸ


๐Ÿฆ‹ Font and string encoding ๐Ÿฆ‹

So once a font is loaded, fvwm figures out its encoding (or charset) from its name โ€” specifically the last two fields of the name. fvwm then assumes that any strings displayed with this font use that same encoding. (One exception, bestie: if an iso10646-1 font is loaded, then UTF-8 is assumed for the string encoding.)

In a normal situation: (i) a font gets loaded by giving a font name without specifying the encoding, (ii) the encoding of the loaded font is the locale encoding, and then (iii) the strings in your fvwm configuration files should use the locale encoding too โ€” same as the window and icon name. With Xft it's a bit different, since Xft only supports iso10646-1 and iso8859-1. If you don't specify one of those encodings in the Xft font name, fvwm does string conversion using (iii). And note โ€” with multibyte fonts (especially "CJK" fonts) for good text rendering, your locale encoding should be the charset of the font. โœจ

Wanna override those rules? You can specify the string encoding right at the beginning of a font description, like this:

StringEncoding=enc:_full_font_name_

where enc is an encoding supported by fvwm (usually the font name charset plus some unicode encodings: UTF-8, USC-2, USC-4 and UTF-16).

For example ๐ŸŒธ โ€” say you've got an iso8859-1 locale charset but you want an FvwmForm in Russian using koi8-r encoding. In that case you just ask FvwmForm to load a koi8-r font by specifying the encoding in the font name. With a multibyte language (and remember, a multibyte font only works well if the locale encoding is the charset of the font), you should use an iso10646-1 font:

StringEncoding=jisx0208.1983-0:-*-fixed-medium-r-*-ja-*-iso10646-1

or

"StringEncoding=jisx0208.1983-0:xft:Bitstream Cyberbit"

if your FvwmForm configuration uses jisx0208.1983-0 encoding. Another possibility: use UTF-8 encoding for your FvwmForm configuration and use an iso10646-1 font:

-*-fixed-medium-r-*-ja-*-iso10646-1

or

"StringEncoding=UTF-8:xft:Bitstream Cyberbit"

or, equivalently,

"xft:Bitstream Cyberbit:encoding=iso10646-1"

In general, iso10646-1 fonts together with UTF-8 string encoding lets you display any characters in a given menu, FvwmForm etc. iconic tbh ๐ŸŒˆ

More and more, unicode is used and text files use UTF-8 encoding. But in practice, the characters you actually use range over your locale charset. So โ€” for saving memory (an iso10646-1 font may have a very large number of characters) or because you've got a pretty font without an iso10646-1 charset โ€” you can specify the string encoding to be UTF-8 and use a font in the locale charset:

StringEncoding=UTF-8:-*-pretty_font-*-12-*

In most cases, fvwm correctly determines the encoding of the font. However, some fonts don't end with valid encoding names. When the font name isn't normal, like this:

-misc-fixed-*--20-*-my_utf8-36

you need to add the encoding after the font name, using a slash as a delimiter. For example:

MenuStyle * Font -misc-fixed-*--20-*-my_utf8-36/iso10646-1

๐Ÿ’… So if fvwm finds an encoding, it uses the iconv system functions to do conversion between encodings. Unfortunately, there are no standards. ๐Ÿ˜ญ For conversion between iso8859-1 and UTF-8: a GNU system uses "ISO-8859-1" and other systems use "iso881" to define the converters (both of these names are supported by fvwm). Moreover, in some cases it may be necessary to use machine specific converters. So if you're experiencing problems, try getting info on your iconv implementation ("man iconv" may help) and put the name that defines the converter between the font encoding and UTF-8 at the end of the font name โ€” after the encoding hint and a /. (Another possible solution is to use GNU libiconv.) For example, use:

Style * Font -misc-fixed-*--14-*-iso8859-1/*/latin1

to use latin1 for defining the converter for the iso8859-1 encoding. The "*" in between the "/" tells fvwm to determine the encoding from the end of the font name. And use:

Style * Font \
-misc-fixed-*--14-*-local8859-6/iso8859-6/local_iso8859_6_iconv

to force fvwm to use the font with iso8859-6 as the encoding (this is useful for bi-directionality) and to use local_iso8859_6_iconv for defining the converters. ๐Ÿซถ


๐ŸŽ€ Font Shadow Effects ๐ŸŽ€

Bestie, fonts can be given 3d effects. โœจ At the beginning of the font name (or just after a possible StringEncoding specification) add:

Shadow=size [offset] [directions]]:

So โ€” size is a positive integer that sets the number of pixels of shadow. offset is an optional positive integer that defines the number of pixels to offset the shadow from the edge of the character, and the default offset is zero. directions is an optional set of directions the shadow emanates from the character. These directions are a space separated list of fvwm directions:

N, North, Top, t, Up, u, -
E, East, Right, r, Right, r, ]
S, South, Bottom, b, Down, d, _
W, West, Left, l, Left, l, [
NE, NorthEast, TopRight, tr, UpRight, ur, ^
SE, SouthEast, BottomRight, br, DownRight, dr, >
SW, SouthWest, BottomLeft, bl, DownLeft, dl, v
NW, NorthWest, TopLeft, tl, UpLeft, ul, <
C, Center, Centre, .

A shadow gets displayed in each given direction. All is equivalent to all the directions. The default direction is BottomRight. With the Center direction, the shadow surrounds the whole string โ€” and since that's a super set of all the other directions, it's a waste of time to specify this along with any other directions. ๐Ÿ’€

The shadow effect only works with colorsets. The color of the shadow is defined by using the fgsh option of the Colorset command โ€” go check the Colorsets section for the deets about colorsets. ๐ŸŽจ

Note: it can be difficult to find the font, fg, fgsh and bg colors to make this effect look good... but it can look quite good. ๐Ÿ‘‘๐ŸŒธ

๐ŸŒ BI-DIRECTIONAL TEXT ๐Ÿ’ซ

okay so Arabic and Hebrew text literally cannot be shown correctly without bi-directional text support, bestie. what that means is that logical strings should be converted before their visual presentation, so the left-to-right and right-to-left sub-strings get figured out and reshuffled. in fvwm this happens automatically in window titles, menus, module labels and other places โ€” but only if the fonts you're using for displaying that text are one of the charsets that require bidi (bi-directional) support. for example that includes iso8859-6, iso8859-8 and iso10646-1 (unicode), but not other iso8859-* fonts. ๐Ÿ™ˆ

this whole bi-directional text support thing is done using the fribidi library compile time option, so go peek at INSTALL.fvwm for that. โœจ


โŒจ๏ธ KEYBOARD SHORTCUTS ๐Ÿฆ‹

almost all window manager operations can be performed from the keyboard, so mouse-less operation should be possible. no mouse, no problem, periodt. ๐Ÿ’…

on top of scrolling around the virtual desktop by binding the Scroll command to appropriate keys, Popup, Move, Resize, and literally any other command can be bound to keys too. once a command is started, the pointer is moved by using the up, down, left, and right arrows, and the action is terminated by pressing return. holding down the Shift key causes the pointer movement to go in larger steps, and holding down the control key causes the pointer movement to go in smaller steps. and if you're an emacs or vi girlie, standard emacs and vi cursor movement controls can be used instead of the arrow keys. iykyk. ๐ŸŒธ


๐Ÿ’พ SESSION MANAGEMENT ๐ŸŽ€

fvwm supports session management according to the X Session Management Protocol. it saves and restores window position, size, stacking order, desk, stickiness, shadiness, maximizedness, iconifiedness for all windows. plus, some global state is saved too. the whole vibe gets remembered. ๐Ÿซถ

but here's the tea: fvwm does not save any information regarding styles, decors, functions or menus. if you change any of these resources during a session (e.g. by issuing Style commands or by using various modules), those changes are lost after saving and restarting the session. ๐Ÿ˜ญ to become permanent, such changes have to be added to the configuration file. no shortcuts, bestie.

โœ… BOOLEAN ARGUMENTS ๐Ÿ‘‘

a number of commands take one or several boolean arguments. these take a few equivalent inputs:

  • "yes", "on", "true", "t" and "y" โ€” all evaluate to true
  • "no", "off", "false", "f" and "n" โ€” all evaluate to false

some commands allow "toggle" too, which means that the feature is disabled if it is currently enabled and vice versa. so flip-floppy of it. ๐Ÿ’…


๐Ÿ–ฑ๏ธ BUILTIN KEY AND MOUSE BINDINGS ๐Ÿ”ฅ

the following commands are built-in to fvwm:

Key Help R A Popup MenuFvwmRoot
Key F1 R A Popup MenuFvwmRoot
Key Tab A M WindowList Root c c NoDeskSort
Key Escape A MC EscapeFunc

Mouse 1 R A Menu MenuFvwmRoot
Mouse 1 T   A FuncFvwmRaiseLowerX Move
Mouse 1 FS  A FuncFvwmRaiseLowerX Resize
Mouse 2 FST A FuncFvwmRaiseLowerX Move

AddToFunc FuncFvwmRaiseLowerX
+ I Raise
+ M $0
+ D Lower

so the Help and F1 keys invoke a built-in menu that fvwm creates. this is primarily for new users that have not created their own configuration file. either key on the root (background) window pops up a menu to help you get started. welcome to the family, baby. โœจ

the Tab key pressed anywhere with the Alt key (same as the key on PC keyboards) held down pop-ups a window list. ๐ŸŒˆ

mouse button 1 on the title-bar or side frame can move, raise or lower a window. ๐Ÿ’…

mouse button 1 on the window corners can resize, raise or lower a window. ๐ŸŽ€

you can override or remove these bindings. to remove the window list binding, use this:

Key Tab A M -

โšก COMMAND EXECUTION โšก

๐Ÿงฉ Module and Function Commands

if fvwm encounters a command that it doesn't recognize, it checks to see if the specified command should have been

Function (rest of command)

or

Module (rest of command)

this allows complex functions or modules to be invoked in a manner which is fairly transparent to the configuration file. sneaky but make it seamless. ๐Ÿ˜Œ

Example: the config file contains the line

HelpMe

fvwm looks for an fvwm command called "HelpMe", and fails. next it looks for a user-defined complex function called "HelpMe". if no such function exists, fvwm tries to execute a module called "HelpMe". three strikes and it's like, okay bestie, module it is. ๐Ÿ’€

โณ Delayed Execution of Commands

Note: there are many commands that affect look and feel of specific, some or all windows, like Style, Mouse, Colorset, TitleStyle and many others. for performance reasons such changes are not applied immediately but only when fvwm is idle, i.e. no user interaction or module input is pending. specifically, new Style options that are set in a function are not applied until after the function has completed. this can sometimes lead to unwanted effects. ๐Ÿ™ˆ

to force that all pending changes are applied immediately, use the UpdateStyles, Refresh or RefreshWindow commands. slay, instant gratification. โœจ


๐Ÿ”ค QUOTING ๐Ÿ’ฌ

quotes are required only when needed to make fvwm consider two or more words to be a single argument. unnecessary quoting is allowed, so don't stress. if you want a quote character in your text, you must escape it by using the backslash character. for example, if you have a pop-up menu called "Window-Ops", then you do not need quotes:

Popup Window-Ops

but if you replace the dash with a space, then you need quotes:

Popup "Window Ops"

the supported quoting characters are double quotes, single quotes and reverse single quotes. all three kinds of quotes are treated in the same way. single characters can be quoted with a preceding backslash. quoting single characters works even inside other kinds of quotes. iconic behavior honestly. ๐Ÿ‘‘


๐Ÿ’ฅ COMMAND EXPANSION ๐Ÿ’ฅ

whenever an fvwm command line is executed, fvwm performs parameter expansion. a parameter is a '$' followed by a word enclosed in brackets ($[...]) or a single special character. if fvwm encounters an unquoted parameter on the command line it expands it to a string indicated by the parameter name. unknown parameters are left untouched. parameter expansion is performed before quoting. to get a literal '$' use "$$". ๐Ÿซถ

if a command is prefixed with a '-' parameter expansion isn't performed. this applies to the command immediately following the '-', in which the expansion normally would have taken place. when used together with other prefix commands it must be added before the other prefix.

Example:

Pick -Exec exec xmessage '$[w.name]'

opens an xmessage dialog with "$[w.name]" unexpanded. ๐Ÿ˜Œ

the longer variables may contain additional variables inside the name, which are expanded before the outer variable.

in earlier versions of fvwm, some single letter variables were supported. it is deprecated now, since they cause a number of problems. you should use the longer substitutes instead. bestie, please, upgrade your ways. ๐Ÿ’…

Example:

# Print the current desk number, horizontal page number
# and the window's class (unexpanded here, no window).
Echo $[desk.n] $[page.nx] $[w.class]
Note: if the command is called outside a window context, it prints "$[w.class]" instead of the class name. it is usually not enough to have the pointer over a window to have a context window. to force using the window with the focus, the Current command can be used:
Current Echo $[desk.n] $[page.nx] $[w.class]

the parameters known by fvwm are:

  • $$ โ€” a literal '$'.
  • $. โ€” the absolute directory of the currently Read file. intended for creating relative and relocatable configuration trees. if used outside of any read file, the returned value is '.'.
  • $0 to $9 โ€” the positional parameters given to a complex function (a function that has been defined with the AddToFunc command). "$0" is replaced with the first parameter, "$1" with the second parameter and so on. if the corresponding parameter is undefined, the "$..." is deleted from the command line.
  • $* โ€” all positional parameters given to a complex function. this includes parameters that follow after "$9".
  • $[n] โ€” the n:th positional parameter given to a complex function, counting from 0. if the corresponding parameter is undefined, the "$[n]" is deleted from the command line. the parameter is expanded unquoted.
  • $[n-m] โ€” the positional parameters given to a complex function, starting with parameter n and ending with parameter m. if all the corresponding parameters are undefined, the "$[...]" is deleted from the command line. if only some of the parameters are defined, all defined parameters are expanded, and the remaining silently ignored. all parameters are expanded unquoted.
  • $[n-] โ€” all the positional parameters given to a complex function, starting with parameter n. if all the corresponding parameters are undefined, the "$[...]" is deleted from the command line. all parameters are expanded unquoted.
  • $[*] โ€” all the positional parameters given to a complex function. this is equivalent of $[0-].
  • $[version.num] โ€” the version number, like "2.6.0".
  • $[version.info] โ€” the version info, which contains the SHA of the latest commit (if compiled from git), or "(relesaed)" if a compiled from a release tarball.
  • $[version.line] โ€” the first line printed by the --version command line option.
  • $[vp.x] $[vp.y] $[vp.width] $[vp.height] โ€” either coordinate or the width or height of the current viewport.
  • $[wa.x] $[wa.y] $[wa.width] $[wa.height] โ€” either coordinate or the width or height of the EWMH working area.
  • $[dwa.x] $[dwa.y] $[dwa.width] $[dwa.height] โ€” either coordinate or the width or height of the dynamic EWMH working area.
  • $[desk.count] โ€” the number of desktops defined with the DesktopName command.
  • $[desk.n] โ€” the current desk number.
  • $[desk.name<n>] โ€” these parameters are replaced with the name of the desktop number <n> that is defined with the DesktopName command. if no name is defined, then the default name is returned.
  • $[desk.width] $[desk.height] โ€” the width or height of the whole desktop, i.e. the width or height multiplied by the number of pages in x or y direction.
  • $[desk.pagesx] $[desk.pagesy] โ€” the number of total pages in a desk in x or y direction. this is the same as the values set by DesktopSize.
  • $[page.nx] $[page.ny] โ€” the current page numbers, by X and Y axes, starting from 0. page is equivalent to area in the GNOME terminology.
  • $[w.id] โ€” the window-id (expressed in hex, e.g. 0x10023c) of the window the command was called for or "$[w.id]" if no window is associated with the command.
  • $[w.name] $[w.iconname] $[w.class] $[w.resource] $[w.visiblename] $[w.iconfile] $[w.miniiconfile] $[w.iconfile.svgopts] $[w.miniiconfile.svgopts] โ€” okay so these give you the window's name, its icon name, the resource class and resource name, the visible name, the file name of its icon or mini icon (the ones you set with the Icon or MiniIcon style โ€” and yes bestie, it includes the full path if the file was actually found on disk ๐Ÿ’…), and โ€” if fvwm got compiled with SVG support โ€” the icon or mini icon svg rendering options (with the leading colon, obviously). If there's no window tied to the command? You just get the unexpanded "$[w.<attribute>]" string back. Sorry babe. ๐Ÿ™ˆ
Heads up: the first 5 variables can literally contain any kind of character, so they come pre-quoted. Meaning the value is wrapped in single quotes, and any single quote inside gets a backslash slapped in front of it. This is why stuff like this: Style $[w.resource] Icon norm/network.png actually works right, no matter what chaotic symbols are hiding in the value โ€” spaces, weird quotes, all of it. Periodt.

For the window's visible name: that's the value from the literal title shown in the titlebar. Usually it'll be the same as $[w.name] once expanded, but if you're using IndexedWindowName then the distinction actually matters and lets you reference a specific window by its visible name โ€” super handy for dropping into things like Style commands. ๐ŸŒธ

  • $[w.x] $[w.y] $[w.width] $[w.height] โ€” the coordinate, width, or height of the current window, as long as it's not iconified. No window associated with the command, or the window is iconified? The string just stays as-is. No notes. ๐Ÿ’€
  • $[w.pagex] $[w.pagey] โ€” the X or Y page the window is sitting on.
  • $[w.desk] โ€” the number of the desk the window is shown on. If the window is sticky, it uses the current desk number instead.
  • $[w.layer] โ€” the layer of the window.
  • $[w.screen] โ€” the screen name the window is on.
  • $[cw.x] $[cw.y] $[cw.width] $[cw.height] โ€” these behave like $[w.โ€ฆ] but they hand you the geometry of the client part of the window. Translation? The border and title are NOT counted. Just the vibes of the actual client area. โœจ
  • $[i.x], $[it.x], $[ip.x] $[i.y], $[it.y], $[ip.y] $[i.width], $[it.width], $[ip.width] $[i.height], $[it.height], **$[ip.height] โ€” same energy as $[w.โ€ฆ] but they give you the geometry of the icon ($[i.โ€ฆ]), the icon title ($[it.โ€ฆ]), or the icon picture ($[ip.โ€ฆ]).
  • $[pointer.x] $[pointer.y] โ€” the position of the pointer on the screen. Pointer not on the screen? Not expanded, bestie.
  • $[pointer.wx] $[pointer.wy] โ€” the position of the pointer inside the selected window. If the pointer isn't on the screen, or the window is iconified, or nothing's selected โ€” these do not expand.
  • $[pointer.cx] $[pointer.cy] โ€” the position of the pointer in the client portion of the selected window. Not expanded if the pointer's off-screen, the window is shaded or iconified, or no window is selected.
  • $[pointer.screen] โ€” the screen name the pointer is currently on.
๐Ÿšจ This one is deprecated โ€” use $[monitor.current] instead, queen.
  • $[monitor.<n>.x], $[monitor.<n>.y], $[monitor.<n>.width], $[monitor.<n>.height], $[monitor.<n>.desk], $[monitor.<n>.pagex], $[monitor.<n>.pagey] $[monitor.primary], $[monitor.prev_primary], $[monitor.current], $[monitor.prev] $[monitor.output], $[monitor.number] $[monitor.count], $[monitor.<n>.prev_desk], $[monitor.<n>.prev_pagex], $[monitor.<n>.prev_pagey] โ€” this whole lil family returns info about the selected monitor. And yes, they nest, so you can do things like:
$[monitor.$[monitor.primary].width]

<n> should be a valid xrandr(1) output name. The breakdown:

  • "x" โ†’ the monitor's x position
  • "y" โ†’ the monitor's y position
  • "width" โ†’ the monitor's width (in pixels)
  • "height" โ†’ the monitor's height (in pixels)
  • "number" โ†’ the monitor's position within the tree. Peep the RANDR SUPPORT section for the deets.
  • "current" โ†’ same thing as the deprecated $[screen.pointer] variable: the monitor that has the mouse pointer ๐Ÿ–ฑ๏ธ
  • "prev" โ†’ the previously focused monitor, or an empty string if there isn't one
  • "count" โ†’ the number of active monitors
  • "desk" โ†’ the current desk displayed on the referenced monitor
  • "pagex" โ†’ the X page on the referenced monitor
  • "pagey" โ†’ the Y page of the referenced monitor
  • "primary" โ†’ the name of the output set as primary via xrandr(1)
  • "prev_primary" โ†’ the name of the output that was the previous primary monitor
  • "prev_desk" โ†’ the previous desk on the referenced monitor
  • "prev_pagex" โ†’ the previous X page on the referenced monitor
  • "prev_pagey" โ†’ the previous Y page on the referenced monitor
  • $[screen] โ€” the screen number fvwm is running on. Super useful for multi-screen setups, fr.
  • $[screen.count] โ€” the total number of screens detected.
๐Ÿšจ Also deprecated โ€” use $[monitor.count] instead.
  • $[fg.cs<n>] $[bg.cs<n>] $[hilight.cs<n>] $[shadow.cs<n>] $[fgsh.cs<n>] โ€” these get replaced with the name of the foreground (fg), background (bg), hilight (hilight), shadow (shadow), or font shadow (fgsh) color defined in colorset <n> (swap <n> for zero or a positive integer, babes). So "$[fg.cs3]" expands to the name of the foreground color of colorset 3 โ€” in rgb:rrrr/gggg/bbbb form. ๐ŸŒˆ

Append .lighten<p> or .darken<p> and you get a color that's lighter or darker than the one in colorset <n> by a percentage <p> (between 0 and 100). So "$[bg.cs3.lighten15]" = the background color of colorset 3, then lightened 15% (again, rgb:rrrr/gggg/bbbb form).

Append .hash at the end and the color output switches to #rrggbb form instead of rgb:rrrr/gggg/bbbb. Like $[bg.cs3.hash] or $[bg.cs3.lighten15.hash]. ๐Ÿ’…

Wanna know more about colorsets? Slide over to the Colorsets section, bestie.

  • $[math.+.<x>,<y>] $[math.-.<x>,<y>] $[math.*.<x>,<y>] $[math./.<x>,<y>] $[math.%.<x>,<y>] $[math.^.<x>,<y>] $[math.<.<x>,<y>] $[math.>.<x>,<y>] โ€” the math expansion variables, for when you need to do some basic arithmetic on the integers <x> and <y>. Available moves: add (+), subtract (-), multiply (*), divide (/), modulus (%), and exponentiation (^). Maximum (>) gives you the greater of two values, minimum (<) gives you the lesser. This is a moment when you're computing panel sizes or window locations relative to a monitor โ€” for example:
$[math.-.$[monitor.$[monitor.primary].height],200]

will subtract 200 pixels from the height of the primary monitor. And yes, you can nest them for extra complex operations:

$[math.+.$[math.*.3,5],$[math.-.4,-2]]

gets replaced with 21. Ate. ๐Ÿ”ฅ

The comma in "<x>,<y>" is there to leave room for a possible future with floats. All operations use C integer mathematics, so the result of integer division is the quotient, and modulus gets you the remainder of the integer division. Watch out: C modulus returns negative remainders for negative values. And finally, the exponentiation operation returns 1 if <y> is negative.

  • $[schedule.last] โ€” replaced by the id of the last command scheduled with the Schedule command, even if that command already ran.
  • $[schedule.next] โ€” replaced by the id the next command used with Schedule will get (unless you explicitly specified a different id).
  • $[cond.rc] โ€” the return code of the last conditional command. Only valid inside a function, and it can't be used in a conditional command. Check the Conditional Commands section in the command list for more.
  • $[func.context] โ€” the context character of the running command, like the one used in the Mouse, Key, or PointerKey command. Handy for stuff like:
Mouse 3 FS N WindowShade $$[func.context]
  • $[debuglog.state] โ€” either 0 (debug log closed) or 1. Tells you the current state of the debugging and logging facility.
  • $[gt.str] โ€” returns the translation of str by peeking in the current locale catalogs. No translation found? str comes back as-is. See the LocalePath command. ๐Ÿฆ‹
  • $[infostore.key] โ€” returns the value of the item stored in the InfoStore at the given key. No key present? You get the unexpanded string back.
  • $[...] โ€” if the string inside the braces isn't any of the above, fvwm tries to find an environment variable with that name and swaps in its value if one exists (so "$[PAGER]" could turn into "more"). Otherwise, the string stays exactly as it is. Some examples live in the description of the AddToFunc command. โœจ

๐Ÿ’– SCRIPTING AND COMPLEX FUNCTIONS ๐Ÿ’–

okay so to pull off the truly complex effects, fvwm has a whole arsenal of commands that level up its scripting game. You can read scripts from a file with Read, from the output of a command with PipeRead, or write them as a complex function with the AddToFunc command. For the curious girlies, section 7 of the fvwm FAQ shows some real-life applications of scripting. ๐Ÿ‘‘

Head to the User Functions and Shell Commands and Conditional Commands sections for the details.

โš ๏ธ A word of warning though: while a complex function is executing, fvwm has to take all input from the mouse pointer (the pointer is "grabbed," in X slang). No other programs can get any input from the pointer while a function is running, and this can confuse some programs. For example, xwd refuses to make screen shots when it's run from a complex function. Wanna do the same thing anyway? Use the Read or PipeRead command instead. No cap. ๐Ÿ™ˆ

Before a menu can even open, it has to be populated with menu items using the AddToMenu command and then bound to a key or mouse button with the Key, PointerKey, or Mouse command (and honestly there are so many other ways to invoke a menu too). Usually you do all of this in the configuration file.

fvwm menus are extremely configurable in look and feel โ€” like, even the tiniest little nuances can be changed to your exact liking. The menu item fonts, the background, the delays before sub menus pop up, generating menus dynamically, and so much more. Go read the MenuStyle command to learn all about it, bestie. ๐Ÿ’…

๐ŸŽ€ Types of Menus ๐ŸŽ€

There are four slightly different types of menus:

Popup menus can literally pop up anywhere on the screen โ€” all on their own, or attached to some part of a window ๐Ÿซถ. The Popup command is what opens them. And here's the vibe: if the popup was invoked with a mouse button held down, it closes the moment you let go, the item under the pointer gets activated, and its action runs. Periodt.

Normal menus are super similar, just slightly more transient โœจ. When you invoke one by clicking a mouse button, it stays open and you can navigate it with no button held. But if you invoke it by a button press followed by mouse motion, it acts exactly like a popup menu. The Menu command is the one that creates normal menus.

"Sub menus" are menus inside other menus ๐Ÿ’…. When you select a menu item whose action is the Popup command, the named menu opens as a sub menu of the parent. Any type of menu can have sub menus, no cap.

"Tear off menus" are menus that got torn off their original context on the desktop and now live like a normal window ๐Ÿ‘‘. You make them from other menus with certain key presses or mouse sequences, or with the TearMenuOff command from inside a menu.

A menu is made up of any number of:

  • titles โ€” inactive menu items, usually chilling at the top of the menu
  • normal items โ€” they trigger various actions when selected
  • separator lines โ€” between the items
  • tear off bars โ€” a horizontal broken line that tears the menu off when selected
  • sub menu items โ€” marked with a triangle pointing left or right, depending on which direction the sub menu appears in

All of the above are optional, bestie. Mix and match ๐ŸŒธ.

Also! If the menu is too long to fit on the screen, the excess items get shoved into a continuation menu, and a sub menu with the string "More..." lands at the bottom of the menu. The "More..." string honors your locale settings ๐ŸŒˆ.

And finally, there might be a picture running up either side of the menu โ€” that's a "side bar" ๐ŸŽ€.

Menus are navigated with the keyboard and the mouse. Lots of people prefer the mouse, but honestly it can be tedious ๐Ÿ˜ญ. Keyboard navigation can be way faster. While fvwm displays a menu, it can do nothing else โ€” like, new windows don't appear before the menu is closed. Though that's not exactly true for tear off menus ๐Ÿ‘€. See the Tear Off Menus section for the details.

Mouse Navigation

Move the pointer over a menu and it selects the item below it. Normally that's shown by a 3d border around the item, but not all parts of a menu can be selected, jsyk. Pressing any mouse button while a menu is open activates the item below it by default. Items of a popup menu are also activated by releasing a held mouse button ๐Ÿ–ฑ๏ธ. If it's an item that hides a sub menu, the sub menu appears when the pointer hovers over the item long enough or moves close to the triangle indicating the sub menu. You can tune all this with menu styles โœจ.

Scrolling a mouse wheel over a menu does one of three things, depending on the MouseWheel menu style:

  • wraps the pointer along the menu (default)
  • scrolls the menu under the pointer
  • acts as if the menu was clicked

Clicking on a selected item activates it โ€” what exactly happens depends on the type of the item.

Clicking on a title, a separator, the side bar, or outside the menu closes the menu (exception: tear off menus can't be closed this way ๐Ÿ™ˆ). Pressing mouse button 2 over a menu title, or activating a tear off bar, creates a tear off menu from the current menu. Clicking a normal menu item invokes the command bound to it. Clicking a sub menu item either closes all open menus and replaces them with the sub menu, or posts the menu (default).

Posting menus is meant to ease mouse navigation ๐Ÿ’–. Once a sub menu is posted, only items from that sub menu can be selected. This is so useful when your pointer keeps straying off the menu, ngl. To unpost the menu and get back to normal operation, either click the same sub menu item again or press any key.

Keyboard Navigation

Just like with mouse navigation, the item below the pointer is selected โ€” achieved by warping the pointer to the menu items when necessary ๐Ÿงš. While a menu is open, all key presses are intercepted by the menu. No other application can get keyboard input (though that's not the case for tear off menus).

Items can be selected directly by pressing a hotkey, configurable individually for each menu item. The hotkey is indicated by underlining it in the menu item label. With the AutomaticHotkeys menu style, fvwm automatically assigns hotkeys to all menu items ๐Ÿ”ฅ.

The most basic keys to navigate through menus are the cursor keys (move up or down one item, enter or leave a sub menu), (activate item) and (close menu).

Numerous other keys can be used to navigate through menus by default:

  • Enter, Return, Space activate the current item.
  • Escape, Delete, Ctrl-G exit the current sequence of menus or destroy a tear off menu.
  • J, N, Cursor-Down, Tab, Meta-Tab, Ctrl-F, move to the next item.
  • K, P, Cursor-Up, Shift-Tab, Shift-Meta-Tab, Ctrl-B, move to the prior item.
  • L, Cursor-Right, F enter a sub menu.
  • H, Cursor-Left, B return to the prior menu.
  • Ctrl-Cursor-Up, Ctrl-K Ctrl-P, Shift-Ctrl-Meta-Tab, Page-Up move up five items.
  • Ctrl-Cursor-Down, Ctrl-J Ctrl-N, Ctrl-Meta-Tab Page-Down move down five items.
  • Shift-P, Home, Shift-Cursor-Up, Ctrl-A move to the first item.
  • Shift-N, End, Shift-Cursor-Down, Ctrl-E move to the last item.
  • Meta-P, Meta-Cursor-Up, Ctrl-Cursor-Left, Shift-Ctrl-Tab, move up just below the next separator.
  • Meta-N, Meta-Cursor-Down, Ctrl-Cursor-Right, Ctrl-Tab, move down just below the next separator.
  • Insert opens the "More..." sub menu if any.
  • Backspace tears off the menu.

The keys and mouse buttons used to navigate the menu can be configured with the Key and Mouse commands using the special context 'M', possibly combined with:

  • 'T' for the menu title
  • 'I' for other menu items
  • 'S' for any border or sidepic
  • '[' for left border including a left sidepic
  • ']' for right border including a right sidepic
  • '-' for top border
  • '_' for bottom border

The menu context uses its own set of actions that can be bound to keys and mouse buttons ๐Ÿ’…. These are:

MenuClose, MenuCloseAndExec, MenuEnterContinuation, MenuEnterSubmenu, MenuLeaveSubmenu, MenuMoveCursor, MenuCursorLeft, MenuCursorRight, MenuSelectItem, MenuScroll and MenuTearOff.

It is not possible to override the key Escape with no modifiers for closing the menu. Neither is it possible to undefine mouse button 1, the arrow keys or the enter key for minimal navigation. That's just the rules, bestie.
  • MenuClose exits from the current sequence of menus or destroys a tear off menu.
  • MenuCloseAndExec exits from the current sequence of menus or destroys a tear off menu and executes the rest of the line as a command.
  • MenuEnterContinuation opens the "More..." sub menu if any.
  • MenuEnterSubmenu enters a sub menu.
  • MenuLeaveSubmenu returns to the prior menu.
  • MenuMoveCursor n [m] moves the selection to another item. If the first argument is zero, the second argument specifies an absolute item in the menu to move the pointer to. Negative items are counted from the end of the menu. If the first argument is non-zero, the second argument must be omitted, and the first argument specifies a relative change in the selected item. The positions may be suffixed with a 's' to indicate that the items should refer only to the first items after separators.
  • MenuCursorLeft enters a sub menu with the SubmenusLeft menu style, and returns to the prior menu with the SubmenusRight menu style.
  • MenuCursorRight enters a sub menu with the SubmenusRight menu style, and returns to the prior menu with the SubmenusLeft menu style.
  • MenuSelectItem triggers the action for the menu item.
  • MenuScroll n performs menu scrolling according to the MouseWheel menu style with n items. The distance can be suffixed with an 's' to indicate the items should refer only to the first items after separators.
  • MenuTearOff turns a normal menu into a "torn off" menu. See Tear Off Menus for details.

Tear Off Menus

A tear off menu is any menu that's been "torn off" the window it was attached to and pinned to the root window ๐Ÿ‘‘. There are three ways to tear off a menu:

  1. click on the menu title with mouse button 2
  2. press the key in the menu
  3. activate its tear off bar (a horizontal bar with a broken line)

Tear off bars must be added to the menu as any other item, by assigning them the command TearMenuOff.

The builtin tear off actions can be overridden by undefining the builtin menu actions bound to tear off. To remove the builtin mouse button 2 binding, use:

Mouse 2 MT A -

and to remove the builtin backspace binding, use:

Key Backspace M A -

See the section Menu Bindings for details on how to assign other bindings for tear off.

Note that prior to fvwm 2.5.20 the tear off mouse bindings were redefined in a different way, which no longer work ๐Ÿ’€.

The window containing the menu is placed as any other window would be. If you find it confusing to have your tear off menus appear at random positions on the screen, put this line in your configuration file:

Style fvwm_menu UsePPosition

To remove borders and buttons from a tear-off menu but keep the menu title, you can use

Style fvwm_menu !Button 0, !Button 1
Style fvwm_menu !Button 2, !Button 3
Style fvwm_menu !Button 4, !Button 5
Style fvwm_menu !Button 6, !Button 7
Style fvwm_menu !Button 8, !Button 9
Style fvwm_menu Title, HandleWidth 0

A tear off menu is a cross breeding between a window and a menu ๐Ÿฆ‹. The menu gets swallowed by a window, its title is stripped off and displayed in the window title. The main advantage? The menu becomes permanent โ€” activating an item does not close the menu. So you can use it over and over without reopening it, iconic. To destroy such a menu, close its window or press the Escape key.

Tear off menus are lowkey their own little species, bestie. They do not take the keyboard focus, but while the pointer is hovering over one of them, every single key press gets yeeted straight to the menu. All your other fvwm key bindings are disabled the whole time the pointer is inside the tear off menu or any of its sub menus. The second the pointer leaves that area, all the sub menus close immediately. Also note: the window holding a tear off menu is never highlighted like it has the focus. It's giving "I'm above all that".

A tear off menu is an independent copy of the menu it came from, fr fr. Which means it is not affected by adding items to that original menu or changing its menu style. Separate queen, separate rules ๐Ÿ’…

To create a tear off menu without opening the normal menu first, you add the option TearOffImmediately to the Menu or Popup command. Iconic.


Building menu contents ๐Ÿงฑ

AddToMenu

  • AddToMenu menu-name [menu-label action] โ€” begins a menu definition, or adds to one.

Typically a menu definition looks like this:

AddToMenu Utilities Utilities Title
 + Xterm           Exec  exec xterm -e tcsh
 + Rxvt            Exec  exec rxvt
 + "Remote Logins" Popup Remote-Logins
 + Top             Exec  exec rxvt -T Top -n Top -e top
 + Calculator      Exec  exec xcalc
 + Xman            Exec  exec xman
 + Xmag            Exec  exec xmag
 + emacs           Exec  exec xemacs
 + Mail            MailFunction xmh "-font fixed"
 + ""              Nop
 + Modules         Popup Module-Popup
 + ""              Nop
 + Exit Fvwm       Popup Quit-Verify

And the menu could be invoked via

Mouse 1 R A Menu Utilities Nop

or

Mouse 1 R A Popup Utilities

There is no end-of-menu symbol. Menus do not have to live in a contiguous region of the config file โ€” they can be scattered all over, no cap. The quoted (or first word) portion in the examples above is the menu label, which is what actually shows up in the menu when the user pops it up. The remaining portion is an fvwm command that runs if the user selects that menu item. An empty menu-label ("") plus the Nop function is how you insert a separator into the menu. Slay.

The keywords DynamicPopUpAction and DynamicPopDownAction have a โœจspecial meaningโœจ when used as the name of a menu item. The action following the keyword is executed whenever the menu is popped up or down. This way you can implement dynamic menus. It is even possible to destroy itself with DestroyMenu and then rebuild from scratch. When the menu has been destroyed (unless you used the recreate option when destroying the menu), do not forget to add the dynamic action again.

Note: Do not trigger actions that require user interaction. They may fail and may screw up your menus. See the Silent command.
Warning: Do not issue MenuStyle commands as dynamic menu actions. Chances are good that this crashes fvwm. ๐Ÿ˜ญ

The keyword Greyed will still render the menu item, but will grey it out, making the option unselectable. It's there, it's just not the moment.

There are several configurable scripts installed together with fvwm for automatic menu generation. They have their own man pages. Some of them, specifically fvwm-menu-directory and fvwm-menu-desktop, may be used with DynamicPopupAction to create a directory listing or GNOME/KDE application listing. Obsessed with them honestly.

Example (File browser):

# You can find the shell script fvwm_make_browse_menu.sh
# in the utils/ directory of the distribution.
AddToMenu BrowseMenu
+ DynamicPopupAction PipeRead \
'fvwm_make_browse_menu.sh BrowseMenu'

Example (Picture menu):

# Build a menu of all .jpg files in
# $HOME/Pictures
AddToMenu JpgMenu foo title
+ DynamicPopupAction Function MakeJpgMenu

AddToFunc MakeJpgMenu
+ I DestroyMenu recreate JpgMenu
+ I AddToMenu JpgMenu Pictures Title
+ I PipeRead 'for i in $HOME/Pictures/*.jpg; \
do echo AddToMenu JpgMenu "`basename $i`" Exec xv $i; done'

The keyword MissingSubmenuFunction has a similar meaning. It is executed whenever you try to pop up a sub menu that does not exist. With this function you can define and destroy menus on the fly, which is main character energy honestly. You can use any command after the keyword, but if the name of an item (that is a submenu) defined with AddToFunc follows it, fvwm executes this command:

Function <function-name> <submenu-name>

i.e. the name is passed to the function as its first argument and can be referred to with "$0".

The fvwm-menu-directory script mentioned above may be used with MissingSubmenuFunction to create an up to date recursive directory listing. Chef's kiss.

Example:

# There is another shell script fvwm_make_directory_menu.sh
# in the utils/ directory of the distribution. To use it,
# define this function in your configuration file:

DestroyFunc MakeMissingDirectoryMenu
AddToFunc MakeMissingDirectoryMenu
+ I PipeRead fvwm_make_directory_menu.sh $0

DestroyMenu SomeMenu
AddToMenu SomeMenu
+ MissingSubmenuFunction MakeMissingDirectoryMenu
+ "Root directory" Popup /

This is another implementation of the file browser that uses sub menus for subdirectories. Two flavours, pick your fave ๐Ÿ“

Titles can be used within the menu. If you add the option top behind the keyword Title, the title is added to the top of the menu. If there was a title already, it is overwritten. Sorry to that old title.

AddToMenu Utilities Tools Title top

All text up to the first Tab in the menu label is aligned to the left side of the menu, all text right of the first Tab is aligned to the left in a second column, and all text thereafter is placed right aligned in the third column. All other Tabs are replaced by spaces. Note that you can change this format with the ItemFormat option of the MenuStyle command. Customisation nation ๐ŸŽ€

If the menu-label contains an ampersand (&), the next character is taken as a hot-key for the menu item. Hot-keys are underlined in the label. To get a literal &, insert &&. Pressing the hot-key moves through the list of menu items with this hot-key, or selects an item that is the only one with this hot-key.

If the menu-label contains a sub-string which is set off by stars, then the text between the stars is expected to be the name of an image file to insert in the menu. To get a literal *, insert "*". For example

+ Calculator*xcalc.xpm* Exec exec xcalc

inserts a menu item labeled "Calculator" with a picture of a calculator above it. The following:

+ *xcalc.xpm*           Exec exec xcalc

Omits the "Calculator" label, but leaves the picture. Still ate.

If the menu-label contains a sub-string which is set off by percent signs, then the text between the percent signs is expected to be the name of an image file (a so called mini icon) to insert to the left of the menu label. A second mini icon that is drawn at the right side of the menu can be given in the same way. To get a literal %, insert %%. For example

+ Calculator%xcalc.xpm% Exec exec xcalc

inserts a menu item labeled "Calculator" with a picture of a calculator to the left. The following:

+ %xcalc.xpm%           Exec exec xcalc

Omits the "Calculator" label, but leaves the picture. The pictures used with this feature should be small (perhaps 16x16). Tiny icons, big vibes โœจ

If the menu-name (not the label) contains a sub-string which is set off by at signs (@), then the text between them is expected to be the name of an image file to draw along the left side of the menu (a side pixmap). You may want to use the SidePic option of the MenuStyle command instead. To get a literal @, insert @@. For example

AddToMenu StartMenu@linux-menu.xpm@

creates a menu with a picture in its bottom left corner.

If the menu-name also contains a sub-string surrounded by ^s, then the text between ^s is expected to be the name of an X11 color and the column containing the side picture is colored with that color. You can set this color for a menu style using the SideColor option of the MenuStyle command. To get a literal ^, insert ^^. Example:

AddToMenu StartMenu@linux-menu.xpm@^blue^

creates a menu with a picture in its bottom left corner and colors with blue the region of the menu containing the picture. Blue era ๐Ÿ’™

In all the above cases, the name of the resulting menu is name specified, stripped of the substrings between the various delimiters. Clean.


DestroyMenu

  • DestroyMenu [recreate] menu โ€” deletes a menu, so that subsequent references to it are no longer valid. You can use this to change the contents of a menu during an fvwm session. The menu can be rebuilt using AddToMenu. The optional parameter recreate tells fvwm not to throw away the menu completely, but to throw away all the menu items (including the title).
DestroyMenu Utilities

Title

Does nothing. It is used to insert a title line in a popup or menu. Literally just there for the aesthetic ๐Ÿ’…


Commands that open menus ๐Ÿšช

  • Menu menu-name [position] [double-click-action] โ€” causes a previously defined menu to be popped up in a sticky manner. That is, if the user invokes the menu with a click action instead of a drag action, the menu stays up. The command double-click-action is invoked if the user double-clicks a button (or hits the key rapidly twice if the menu is bound to a key) when bringing up the menu. If the double click action is not specified, double clicking on the menu does nothing. However, if the menu begins with a menu item (i.e. not with a title or a separator) and the double click action is not given, double clicking invokes the first item of the menu (but only if the pointer really was over the item).

The pointer is warped to where it was when the menu was invoked, if it was both invoked and closed with a keystroke. It remembers where it came from, iconic behaviour honestly.

The position arguments allow placement of the menu somewhere on the screen, for example centered on the visible screen or above a title bar. Basically it works like this: you specify a context-rectangle and an offset to this rectangle, by which the upper left corner of the menu is moved from the upper left corner of the rectangle. The position arguments consist of several parts:

[context-rectangle] x y [special options]

The context-rectangle can be one of:

  • Root โ€” the root window of the current screen.
  • Monitor โ€” the area of the current RandR screen. yeah, that whole monitor.
  • Mouse โ€” a 1x1 rectangle sitting right at the mouse position. tiny. microscopic. iconic.
  • Window โ€” the frame of the context window.
  • Interior โ€” the inside of the context window.
  • Title โ€” the title of the context window, or of the icon.
  • Button<n> โ€” button <n> of the context window. yes bestie, that button.
  • Icon โ€” the icon of the context window.
  • Menu โ€” the current menu.
  • Item โ€” the current menu item.
  • Context โ€” the current window, menu or icon. whatever we're in rn.
  • This โ€” literally whatever widget the pointer is on (like a corner of a window, or the root window). it's giving "it depends" ๐Ÿ’…
  • Rectangle geometry โ€” the rectangle defined by geometry in X geometry format. width and height default to 1 if you omit them.

If the context-rectangle is omitted or invalid (like, say, item on a window), Mouse is the default. and ngl, not all of these make sense in all situations (imagine Icon when the pointer is chilling on a menu ๐Ÿ˜ญ).

The offset values x and y tell you how far the menu gets moved from its default position. by default the number you give is read as a percentage of the context rectangle's width (height), but slap a trailing m on it and it uses the menu's width (height) instead. and a trailing p flips the whole interpretation over to mean pixels.

Instead of one single value you can pass a whole list of values. every extra number after the first one is separated from its predecessor by its sign โ€” do not use any other separators, fr fr.

If x or y are prefixed with o<number> where <number> is an integer, the menu and the rectangle get moved to overlap at that specified position before any other offsets are applied. the menu and the rectangle are placed so that the pixel at <number> percent of the rectangle's width/height is right over the pixel at <number> percent of the menu's width/height. so o0 means the top/left borders of the menu and the rectangle overlap, o100 puts the bottom/right borders together, and o50 centers them on each other (try it and you'll see it's way simpler than this description, trust). the default is o0. the prefix o<number> is shorthand for +<number>-<number>m.

A prefix of c is equivalent to o50. examples, bestie:

# window list in the middle of the screen
WindowList Root c c

# menu to the left of a window
Menu name window -100m c+0

# popup menu 8 pixels above the mouse pointer
Popup name mouse c -100m-8p

# somewhere on the screen
Menu name rectangle 512x384+1+1 +0 +0

# centered vertically around a menu item
AddToMenu foobar-menu
 + "first item" Nop
 + "special item" Popup "another menu" item +100 c
 + "last item" Nop

# above the first menu item
AddToMenu foobar-menu
 + "first item" Popup "another menu" item +0 -100m

Heads up tho: you can put a sub menu super far off from the current menu, so far that you couldn't reach it with the mouse without leaving the menu. but if the pointer leaves the current menu in the general direction of the sub menu, the menu stays up. it just knows. โœจ

๐ŸŽ€ Special options ๐ŸŽ€

Want a tear off menu without ever opening the normal menu first? just add the TearOffImmediately option. normally the menu opens in normal state for a split second before being torn off โ€” this skips that whole moment. and since tearing off places the menu like any other window, you should specify a position explicitly:

# Forbid fvwm to place the menu window
Style <name of menu> UsePPosition
# Menu at top left corner of screen
Menu Root 0p 0p TearOffImmediately

The Animated and Mwm or Win menu styles might move a menu somewhere else on the screen. if that's not the vibe you can add Fixed as an option. this could happen if, for example, you want the menu always in the top right corner of the screen. ๐Ÿ“Œ

Where do you want a menu to appear when you click on its menu item? default is to place the title under the cursor, but if you want it exactly where the position arguments say, use the SelectInPlace option. want the pointer on the title of the menu too? use SelectWarp as well. note that these options only apply if the PopupAsRootMenu MenuStyle option is used.

The pointer gets warped to the title of a sub menu whenever the pointer would be on an item when the sub menu pops up (fvwm menu style), or never warped to the title at all (Mwm or Win menu styles). you can force (or forbid) warping whenever the sub menu is opened with the WarpTitle (NoWarp) option.

Also note that these special-options do work with a normal menu that has no other position arguments. ๐Ÿ’…

Popup PopupName [position] [default-action]

This command has two whole purposes: to bind a menu to a key or mouse button, and to bind a sub menu into a menu. the formats for the two purposes differ slightly. the position arguments are the same as for Menu. the command default-action is invoked if the user clicks a button to invoke the menu and releases it immediately again (or hits the key rapidly twice if the menu is bound to a key). if the default action isn't specified, double clicking on the menu does nothing. BUT โ€” if the menu begins with a menu item (i.e. not with a title or a separator) and the default action is not given, double clicking invokes the first item of the menu (but only if the pointer really was over the item). sneaky.

To bind a previously defined pop-up menu to a key or mouse button:

The following example binds mouse buttons 2 and 3 to a pop-up called "Window Ops". the menu pops up if the buttons 2 or 3 are pressed in the window frame, side-bar, or title-bar, with no modifiers (none of shift, control, or meta).

Mouse 2 FST N Popup "Window Ops"
Mouse 3 FST N Popup "Window Ops"

Pop-ups can be bound to keys through the use of the Key command. pop-ups can be operated without using the mouse by binding to keys and operating via the up arrow, down arrow, and enter keys. keyboard girlies stay winning. โŒจ๏ธ

To bind a previously defined pop-up menu to another menu, for use as a sub menu:

The following example defines a sub menu "Quit-Verify" and binds it into a main menu, called "RootMenu":

AddToMenu Quit-Verify
 + "Really Quit Fvwm?" Title
 + "Yes, Really Quit"  Quit
 + "Restart Fvwm"      Restart
 + ""                  Nop
 + "No, Don't Quit"    Nop

AddToMenu RootMenu "Root Menu" Title
 + "Open XTerm Window" Popup NewWindowMenu
 + "Login as Root"     Exec exec xterm -T Root -n Root -e su -
 + "Login as Anyone"   Popup AnyoneMenu
 + "Remote Hosts"      Popup HostMenu
 + ""                  Nop
 + "X utilities"       Popup Xutils
 + ""                  Nop
 + "Fvwm Modules"      Popup Module-Popup
 + "Fvwm Window Ops"   Popup Window-Ops
 + ""                  Nop
 + "Previous Focus"    Prev (AcceptsFocus) Focus
 + "Next Focus"        Next (AcceptsFocus) Focus
 + ""                  Nop
 + "Refresh screen"    Refresh
 + ""                  Nop
 + "Reset X defaults"  Exec xrdb -load \
                 $HOME/.Xdefaults
 + ""                  Nop
 + ""                  Nop
 + Quit                Popup Quit-Verify

Popup differs from Menu in that pop-ups do not stay up if the user simply clicks. these are popup-menus, which are a little hard on the wrist ๐Ÿ˜ญ. Menu menus stay up on a click action. see the Menu command for an explanation of the interactive behavior of menus. a menu can be open up to ten times at once, so a menu may even use itself or any of its predecessors as a sub menu. recursion? in my window manager? more likely than you think. ๐Ÿ’€

๐ŸŽ€ TearMenuOff ๐ŸŽ€

When assigned to a menu item, it inserts a tear off bar into the menu (a horizontal broken line). activating that item tears off the menu. if the menu item has a label, that label is shown instead of the broken line. if used outside menus, this command does nothing. examples:

AddToMenu WindowMenu
+ I "" TearMenuOff

AddToMenu RootMenu
+ I "click here to tear me off" TearMenuOff

Menu styles describe the looks and behaviour like normal styles do for windows. menu styles are assigned to individual or all menus, and changing the menu style immediately affects all menus that use it. (if a menu style is used from within a menu, the changes are applied the next time an affected menu is opened. so like, next time, bestie.)

โœจ ChangeMenuStyle โœจ

ChangeMenuStyle menustyle menu ...

Changes the menu style of menu to menustyle. you may specify more than one menu in each call of ChangeMenuStyle. bulk edit energy. ๐Ÿ”ฅ

โœจ CopyMenuStyle โœจ

CopyMenuStyle orig-menustyle dest-menustyle

Copy orig-menustyle to dest-menustyle, where orig-menustyle is an existing menu style. if the menu style dest_menustyle does not exist, then it is created.

โœจ DestroyMenuStyle โœจ

DestroyMenuStyle menustyle

Deletes the menu style named menustyle and changes all menus using this style to the default style. you cannot destroy the default menu style. sorry bestie, that one's forever. ๐Ÿ’–

DestroyMenuStyle pixmap1

MenuStyle stylename [options]

Sets a new menu style or changes a previously defined style. the stylename is the style name; if it contains spaces or tabs it has to be quoted. the name "" is reserved for the default menu style. the default menu style is used for every menu-like object (e.g. the window created by the WindowList command) that had not be assigned a style using the ChangeMenuStyle. see also DestroyMenuStyle. when using monochrome color options are ignored. ๐ŸŽ€

  • Fvwm / Mwm / Win
  • BorderWidth
  • HilightBack / !HilightBack
  • HilightTitleBack
  • ActiveFore / !ActiveFore
  • MenuColorset
  • ActiveColorset
  • GreyedColorset
  • TitleColorset
  • Hilight3DThick / Hilight3DThin / Hilight3DOff
  • Hilight3DThickness
  • Animation / !Animation
  • Font
  • TitleFont
  • PopupDelay
  • PopupOffset
  • TitleWarp / !TitleWarp
  • TitleUnderlines0 / TitleUnderlines1 / TitleUnderlines2
  • SeparatorsLong / SeparatorsShort
  • TrianglesSolid / TrianglesRelief
  • PopupImmediately / PopupDelayed
  • PopdownImmediately / PopdownDelayed
  • PopupActiveArea
  • DoubleClickTime
  • SidePic
  • SideColor
  • PopupAsRootMenu / PopupAsSubmenu / PopupIgnore / PopupClose
  • RemoveSubmenus / HoldSubmenus
  • SubmenusRight / SubmenusLeft
  • SelectOnRelease
  • ItemFormat
  • VerticalItemSpacing
  • VerticalMargins
  • VerticalTitleSpacing
  • AutomaticHotkeys / !AutomaticHotkeys
  • UniqueHotkeyActivatesImmediate / !UniqueHotkeyActivatesImmediate
  • MouseWheel
  • ScrollOffPage / !ScrollOffPage
  • TrianglesUseFore / !TrianglesUseFore
  • Translucent / !Translucent

okay so ๐Ÿ’… bestie, some of those lil options up there are grouped as pairs or triples with a / between them, and that slash literally means "these two can't both be true, pick a lane". Every paired option can be negated by slapping a ! in front of it, which gives you the effect of its counterpart. it's giving toggle energy fr fr โœจ


Fvwm, Mwm and Win are the reset buttons, no cap โ€” they set all options back to the style with that same name from former versions of fvwm. And heads up: the default for new menu styles is Fvwm style, periodt.

โš ๏ธ these three override everything else except HilightBack, ActiveFore and PopupDelay โ€” so use them only as the first option for a menu style, or when you wanna reset the style to its defined behaviour. if you'd rather do it manually, you can get the same glow-up by setting all the other options one by one ๐Ÿ’–

Mwm and Win style menus pop sub menus up automatically. Win menus show the current menu item by flipping the background to dark. and the overlap drama: Fvwm sub menus do overlap the parent menu, while Mwm and Win style menus never overlap the parent. iconic behaviour tbh ๐ŸŒธ


๐ŸŒˆ the styles, spelled out

Fvwm style is equivalent to:

!HilightBack, Hilight3DThin, !ActiveFore, !Animation, Font, PopupOffset 0 67,
TitleWarp, TitleUnderlines1, SeparatorsShort, TrianglesRelief, PopupDelayed,
PopdownDelayed, PopupDelay 150, PopdownDelay 150, PopupAsSubmenu, HoldSubmenus,
SubmenusRight, BorderWidth 2, !AutomaticHotkeys,
UniqueHotkeyActivatesImmediate, PopupActiveArea 75.

Mwm style is equivalent to:

!HilightBack, Hilight3DThick, !ActiveFore, !Animation, Font, PopupOffset -3 100,
!TitleWarp, TitleUnderlines2, SeparatorsLong, TrianglesRelief, PopupImmediately,
PopdownDelayed, PopdownDelay 150, PopupAsSubmenu, HoldSubmenus, SubmenusRight,
BorderWidth 2, UniqueHotkeyActivatesImmediate, !AutomaticHotkeys,
PopupActiveArea 75.

Win style is equivalent to:

HilightBack, Hilight3DOff, ActiveFore, !Animation, Font, PopupOffset -5 100,
!TitleWarp, TitleUnderlines1, SeparatorsShort, TrianglesSolid,
PopupImmediately, PopdownDelayed, PopdownDelay 150, PopupAsSubmenu,
RemoveSubmenus, SubmenusRight, BorderWidth 2,
UniqueHotkeyActivatesImmediate, !AutomaticHotkeys, PopupActiveArea 75.

๐ŸŽ€ option by option, bestie

  • BorderWidth โ€” takes the thickness of the border around the menus, in pixels. it can be anywhere from zero to 50 pixels, and the default is 2. lowkey if you feed it an invalid value it just reverts the border width back to the default. rude but fair ๐Ÿ’…
  • HilightBack and !HilightBack โ€” switch hilighting the background of the selected menu item on and off. the ActiveColorset background color is what gets used for that hilight.
  • HilightTitleBack โ€” switches hilighting the background of menu titles on. the TitleColorset background color is used for it.
  • ActiveFore and !ActiveFore โ€” switch hilighting the foreground of the selected menu item on and off. the ActiveColorset foreground color does the hilighting here.
  • MenuColorset โ€” controls the colorset used to color the menu. if that colorset has a pixmap or gradient defined, that's what becomes the background of the menu. and the shape mask from the colorset is used to shape the menu. pls refer to the Colorsets section for the deets on colorsets ๐Ÿฆ‹
  • ActiveColorset โ€” controls the color of the active menu item, as long as the HilightBack or ActiveFore menu styles are in play. if you specify it, the hilight and shadow colors from the colorset get used too. the pixmap and shape mask from the colorset are not used. and you can turn off background or foreground hilighting individually with the !ActiveFore or !HilightBack menu styles.
  • GreyedColorset โ€” works exactly like MenuColorset, except the foreground from the colorset replaces the color you gave with the Greyed menu style. no other parts of the colorset are used. that's it, that's the whole job ๐Ÿซถ
  • TitleColorset โ€” again, works exactly like MenuColorset, but it's used only for menu titles.
  • Translucent โ€” controls a pseudo transparent effect that uses an image of the desktop under the menu as its background image. this one takes one value: a number between 0 (fully translucent) and 100 (not translucent), which is the percent of the translucency. use !Translucent (or just no additional value) to turn the effect off. note that this only applies to normal menus โ€” "torn off" menus don't get it. also, only the menu background is translucent; the HilightBack of the active item and the HilightTitleBack of the title are not. to get a fully translucent menu, do this:
MenuStyle * Translucent 60, !HilightBack, !HilightTitleBack, ActiveFore
  • Hilight3DThick, Hilight3DThin and Hilight3DOff โ€” decide whether the selected menu item gets hilighted with a 3D relief. thick reliefs are two pixels wide, thin reliefs are one pixel wide. cute lil depth moment โœจ
  • Hilight3DThickness โ€” takes one numeric argument that can be between -50 and +50 pixels. with negative values the menu item gets a pressed in look. and fun fact: the three commands above are equivalent to a thickness of 2, 1 and 0.
  • Animation and !Animation โ€” turn menu animation on or off. when animation is on, sub menus that don't fit on the screen cause the parent menu to be shifted to the left so the sub menu can actually be seen. the way it just slides over for its child ๐Ÿ˜ญ๐Ÿ’–
  • Font and TitleFont โ€” take a font name as an argument. if a font by that name exists, it's used for the text of all menu items. if it doesn't exist, or if the name is left blank, the built-in default is used. and if you give a TitleFont, it's used for all menu titles instead of the normal font.
  • PopupDelay โ€” requires one numeric argument. this value is the delay in milliseconds before a sub menu pops up when the pointer moves over a menu item that has a sub menu. if the value is zero, no automatic pop up happens at all. if the argument is omitted, the built-in default is used. note that popup delay has no effect if the PopupImmediately option is used, because sub menus pop up immediately then, obviously ๐Ÿ’€
  • PopupImmediately โ€” makes menu items with sub menus pop up as soon as the pointer enters the item. the PopupDelay option gets ignored then. if PopupDelayed is used instead, fvwm looks at the PopupDelay option to decide if or when that automatic popup happens.
  • PopdownDelay โ€” works exactly like PopupDelay, but it determines the timeout of the PopupDelayed style.
  • PopdownImmediately โ€” makes sub menus vanish as soon as the pointer leaves the sub menu and the corresponding item in the parent menu. with the opposite option, PopdownDelayed, the sub menu only pops down after the time you set with the PopdownDelay option. this is genuinely so handy when your pointer keeps straying off the menu item while you're trying to move into the sub menu, we've all been there ๐Ÿ˜ญ

and for the conflict girlies: whenever there's a clash between the PopupImmediately, PopupDelayed, PopupDelay styles and the PopdownImmediately, PopdownDelayed, PopdownDelay styles โ€” the Popup... styles win when you're navigating with the mouse, and the Popdown... styles win when you're navigating with the keyboard. periodt โŒจ๏ธ

  • PopupOffset โ€” requires two integer arguments. both values affect where sub menus get placed relative to the parent menu. if both values are zero, the left edge of the sub menu overlaps the left edge of the parent menu. if the first value is non-zero, the sub menu is shifted that many pixels to the right (or left if it's negative). if the second value is non-zero, the menu is moved by that many percent of the parent menu's width to the right or left.
  • PopupActiveArea โ€” requires an integer value between 51 and 100. normally, when the pointer is over a menu item with a sub menu and the pointer enters the area that starts at 75% of the menu width, the sub menu is shown immediately. that percentage can be changed with PopupActiveArea. setting the value to 100 disables this kind of automatic popup altogether. the default value is restored if you give no value or an invalid one.
  • TitleWarp and !TitleWarp โ€” affect whether the pointer warps to the menu title when a sub menu is opened or not. but note: regardless of this setting, the pointer is not warped if the menu doesn't pop up under the pointer. rules are rules ๐Ÿ’…
  • TitleUnderlines0, TitleUnderlines1 and TitleUnderlines2 โ€” specify how many lines are drawn below a menu title. 0, 1, 2, pick your aesthetic ๐ŸŽ€
  • SeparatorsLong and SeparatorsShort โ€” set the length of menu separators. long separators run from the left edge all the way to the right edge. short separators leave a few pixels to the edges of the menu.
  • TrianglesSolid and TrianglesRelief โ€” affect how the little triangles for sub menus are drawn. solid triangles are filled with a color, while relief triangles are hollow.
  • DoubleClickTime โ€” requires one numeric argument. this is the time in milliseconds between two mouse clicks in a menu for it to count as a double click. the default is 450 milliseconds. if the argument is omitted, the double click time resets to that default. bestie the default is literally right there, just use it ๐Ÿ™ˆ
  • SidePic โ€” takes the name of an image file as an argument. the picture gets drawn along the left side of the menu. SidePic can be overridden by a menu specific side pixmap (see AddToMenu). if the file name is omitted, an existing side pixmap is removed from the menu style.
  • SideColor โ€” takes the name of an X11 color as an argument. this color is used to color the column containing the side picture (see above ๐Ÿ‘†). SideColor can be overridden by a menu specific side color (see AddToMenu). if the color name is omitted, the side color option is switched off.
  • PopupAsRootMenu, PopupAsSubmenu, PopupIgnore, PopupClose โ€” these four are all about what happens when you click a menu item that opens a sub menu. With PopupAsRootMenu the original menu gets closed before the sub menu shows up. With PopupAsSubmenu it does not close, so you can navigate back into the parent menu. And lowkey the extra sauce on PopupAsSubmenu: the sub menu stays held open (posted) no matter where you move the mouse ๐Ÿ’…. Depending on your menu style that can make navigating way smoother. Any keystroke while a menu is posted snaps the menu back to normal behavior. With PopupClose the menu closes when a sub menu item gets activated, and the menu stays open if PopupIgnore is used (even if the menu was invoked with the Popup command). PopupAsSubmenu is the default.
  • RemoveSubmenus โ€” tells fvwm to remove the sub menu when you move back into the parent menu.
  • HoldSubmenus โ€” the sub menu stays visible instead. You probably want HoldSubmenus if you're using the PopupDelayed style. Heads up: RemoveSubmenus affects menu navigation with the keyboard โŒจ๏ธ.
  • SelectOnRelease โ€” takes an optional key name as an argument. If the given key is released in a menu using this style, the current menu item gets selected. It's intended for WindowList navigation. The key name is a standard X11 key name as defined in /usr/include/X11/keysymdef.h, (without the XK_ prefix), or the keysym database /usr/X11R6/lib/X11/XKeysymDB. To disable this behavior, just omit the key name.
Note: some X servers do not support KeyRelease events. SelectOnRelease does not work on such a machine ๐Ÿ˜ญ.
  • ItemFormat โ€” takes a special string as its argument that decides the layout of the menu items. Think of the format string as if it were a menu item, bestie. All you have to do is tell fvwm where to place the different parts of the menu item (the labels, the triangle denoting a sub menu, the mini icons and the side pic) in the blank area. The string consists of spaces, characters and formatting directives beginning with %. Any invalid characters and formatting directives are silently ignored:
    • %l, %c and %r โ€” insert the next item label. Up to three labels can be used. The item column is left-aligned (%l), centered (%c) or right-aligned (%r).
    • %i โ€” inserts the mini icon.
    • %> and %< โ€” insert the sub menu triangle pointing either to the right (%>) or to the left (%<).
    • %| โ€” the first %| denotes the beginning of the area that is highlighted either with a background color or a relief (or both). The second %| marks the end of this area. %| can be used up to twice in the string. If you do not add one or both of them, fvwm sets the margins to the margins of the whole item (not counting the side picture).
    • %s โ€” places the side picture either at the beginning or the end of the menu. This directive may be used only once and only as the first or last in the format string. If the %s is not at the beginning of the string, menus are not drawn properly ๐Ÿซ .
    • Space, Tab, %Space and %Tab โ€” add a gap of one space, or a tab, using the width of the menu font. When using a tab, the size of the gap can be one to 8 spaces since the tab position is a multiple of 8 from the edge of the menu. The whole string must be quoted if spaces or tabs are used.
    • %p โ€” like Space and Tab, %p inserts an empty area into the item, but with better control of its size (see below).

You can define an additional space before and after each of the objects like this:

%left.rightp

This means: if the object is defined in the menu (e.g. if it is %s and you use a side picture, or it is %l for the third column and there are items defined that actually have a third column), then add left pixels before the object and right pixels after it. You may leave out the left or the .right parts if you do not need them. All values up to the screen width are allowed. Even negative values can be used, with care. The p may be replaced with any other formatting directives described above.

Note: only items defined in the format string are visible in the menus. So if you do not put a %s in there you do not see a side picture, even if one is specified. ๐Ÿ™ˆ
Note: the SubmenusLeft style changes the default ItemFormat string, but if it was set manually it is not modified.
Note: if any unformatted title of the menu is wider than the widest menu item, the spaces between the different parts of the menu items are enlarged to match the width of the title. Leading left aligned objects in the format string (%l, %i, %<, first %|) stick to the left edge of the menu and trailing right aligned objects (%r, %i, %>, second %|) stick to the right edge. The gaps between the remaining items are enlarged equally.

Examples โœจ:

MenuStyle * ItemFormat "%.4s%.1|%.5i%.5l%.5l%.5r%.5i%2.3>%1|"

Is the default string used by fvwm: (side picture + 4 pixels gap) (beginning of the hilighted area + 1 pixel gap) (mini icon + 5p) (first column left aligned + 5p) (second column left aligned + 5p) (third column right aligned + 5p) (second mini icon + 5p) (2p + sub menu triangle + 3p) (1p + end of hilighted area).

MenuStyle * ItemFormat "%.1|%3.2<%5i%5l%5l%5r%5i%1|%4s"

Is used by fvwm with the SubmenusLeft option below.

  • VerticalItemSpacing and VerticalTitleSpacing โ€” control the vertical spacing of menu items and titles like ItemFormat controls the horizontal spacing. Both take two numeric arguments that may range from -100 to +100. The first is the gap in pixels above a normal menu item (or a menu title), the second is the gap in pixels below it. Negative numbers do not make much sense and may screw up the menu completely ๐Ÿ’€. If no arguments are given or the given arguments are invalid, the built-in defaults are used: one pixel above the item or title and two below.
  • VerticalMargins โ€” can be used to add some padding at the top and bottom of menus. It takes two numeric arguments that must be positive integers (or zero). If the number of arguments or its values are incorrect, fvwm defaults both to 0, which means no padding at all. If the values are correct, the first one is used for the top margin, and the second one is used for the bottom margin.
  • SubmenusLeft โ€” mirrors the menu layout and behavior. Sub menus pop up to the left, the sub menu triangle is drawn left and the mini icon and side picture are drawn at the right side of the menu. The default is SubmenusRight. The position hints of a menu are also affected by this setting, i.e. position hints using item or menu as context rectangle and position hints using m offsets.
  • AutomaticHotkeys and !AutomaticHotkeys โ€” control the menu's ability to automatically provide hot-keys on the first character of each menu item's label. This behavior is always overridden if an explicit hot-key is assigned in the AddToMenu command.
  • UniqueHotkeyActivatesImmediate and !UniqueHotkeyActivatesImmediate โ€” control how menu items are invoked when used with hotkeys. By default, if a given menu entry only has one completeable match for a given hotkey, the action for that menu entry is invoked and the menu is closed. This is due to the UniqueHotkeyActivatesImmediate option. However, the menu can be told to remain open, waiting for the user to invoke the selected item instead when there is only one matched item for a given hotkey, by using the !UniqueHotkeyActivatesImmediate option.
  • MouseWheel โ€” controls the ability to scroll the menu using a mouse wheel. It takes one argument, that can be one of ScrollsPointer, ScrollsMenu, ScrollsMenuBackwards or ActivatesItem. ScrollsPointer makes the mouse wheel scroll the pointer over a menu โ€” this is the default. ScrollsMenu and ScrollsMenuBackwards scroll the menu beneath the pointer. ActivatesItem disables scrolling by mouse wheel and makes the use of a mouse wheel act as if the menu was clicked. If no argument is supplied the default setting is restored.
  • ScrollOffPage โ€” allows a menu to be scrolled out of the visible area if MouseWheel is set to ScrollsMenu or ScrollsMenuBackwards. This is the default. The opposite, !ScrollOffPage, disables this behaviour.
  • TrianglesUseFore โ€” draws sub menu triangles with the foreground color of the menu colorset (normally drawn with the hilight color). !TrianglesUseFore disables this behaviour.

๐ŸŒˆ LIST OF FVWM COMMANDS ๐ŸŒˆ

The command descriptions below are grouped together in the following sections. The sections are hopefully sorted in order of usefulness to the newcomer ๐Ÿซถ.

  • Menu commands
  • Miscellaneous commands
  • Commands affecting window movement and placement
  • Commands for focus and mouse movement
  • Commands controlling window state
  • Commands for mouse and key bindings
  • The Style command (controlling window styles)
  • Other commands controlling window styles
  • Commands controlling the virtual desktop
  • Commands for user functions and shell commands
  • Conditional commands
  • Module commands
  • Quit, restart and session management commands
  • Colorsets
  • Color gradients

๐Ÿ› ๏ธ Miscellaneous Commands ๐Ÿ› ๏ธ

BugOpts [option [bool]], ...

This command controls several workarounds for bugs in third party programs ๐Ÿ›. The individual options are separated by commas. The optional argument bool is a boolean argument and controls if the bug workaround is enabled or not. It can either be "True" or "False" to turn the option on or off, or "toggle" to switch is back and forth. If bool is omitted, the default setting is restored.

  • DebugRandR โ€” activates monitor layout debug messages.
  • FlickeringMoveWorkaround โ€” disables ConfigureNotify events that are usually sent to an application while it is moved. If some windows flicker annoyingly while being moved, this option may help you. Note that if this problem occurs it is not an fvwm bug, it is a problem of the application.
  • MixedVisualWorkaround โ€” this one makes fvwm install the root colormap before it does some operations that use the root window visuals. It's only useful when the -visual option is used to start fvwm, and even then only with some configs of some servers (like Exceed 6.0 with an 8 bit PseudoColor root and fvwm using a 24 bit TrueColor visual). niche but iconic ๐Ÿ’…
  • ModalityIsEvil โ€” controls whether Motif applications get to have modal dialogs (aka those dialogs that trap you and force you to close them first before you can do literally anything else ๐Ÿ˜ญ). The default is to not allow apps to have modal dialogs. Use this option with care, bestie. Once you turn this option on, you have to restart fvwm to turn it off. no take-backs ๐Ÿ’€
  • RaiseOverNativeWindows โ€” makes fvwm try to raise the windows it manages over the native windows of the X server's host system. This is needed for some X servers running under Windows, Windows NT or Mac OS X. Fvwm tries to detect if it's running under such an X server and initializes the flag accordingly. she's self-aware โœจ
  • RaiseOverUnmanaged โ€” makes fvwm try to raise the windows it manages over override_redirect windows. This is used to cope with ill-mannered applications that use long-lived windows of this sort, contrary to ICCCM conventions ๐Ÿ˜ค. It's useful with the Unmanaged style option too.
  • FlickeringQtDialogsWorkaround โ€” suppresses flickering of the focused window in some modules when using KDE or QT applications with application modal dialog windows. By default this option is turned on. Heads up though: this option may be visually disturbing for other applications using windows not managed by fvwm. Since those apps are rare, it's most likely safe to leave this option at its default. ๐Ÿฆ‹
  • QtDragnDropWorkaround โ€” suppresses the forwarding of unknown ClientEvent messages to windows โ€” usually that's harmless, but Qt has problems handling unrecognised ClientEvent messages. So enabling this option might help for Qt applications using DragnDrop. This option is off by default.
  • EWMHIconicStateWorkaround โ€” needed by EWMH compliant pagers or taskbars that represent windows which are on a different desktops as iconified. These pagers and taskbars use a version of the EWMH specification before version 1.2 (the current KDE 2 & 3 versions). They use the IconicState WM_STATE state to figure out if an application is iconified. But this state, according to the ICCCM, does not imply that a window is iconified (in the usual sense). Turning on this option forces fvwm to establish an equivalence between the IconicState WM_STATE state and the iconified window. This violates ICCCM compliance but shouldn't cause big problems. By default this option is off. ๐Ÿ™ˆ
  • DisplayNewWindowNames โ€” with this enabled, fvwm prints the name, icon name (if available), resource and class of new windows to the console. This can help in finding the correct strings to use in the Style command. detective mode ๐Ÿ”
  • ExplainWindowPlacement โ€” when this is enabled, fvwm prints a message to the console whenever a new window is placed or PlaceAgain is used. The message explains on which desk, page, screen and position it was placed and why. Use this to figure out why a specific window doesn't appear where you think it should. it's giving investigative journalism ๐Ÿ’…
  • DebugCRMotionMethod โ€” enables some debugging code in the ConfigureRequest handling routines of fvwm. It's not helpful for the user, but if you report a bug to the fvwm team we may ask you to enable this option. ๐Ÿ˜Œ
  • TransliterateUtf8 โ€” enables transliteration during conversions from utf-8 strings. By default fvwm will not transliterate during conversion, but will fall back to alternate strings provided by the clients if conversion from utf-8 fails due to characters which have no direct correspondence in the target character set. Some clients however neglect to set non utf-8 properties correctly, in which case this option may help. ๐Ÿซถ

โœจ BusyCursor [Option bool], ... โœจ

This command controls the cursor during the execution of certain commands. ๐ŸŽ€

Option can be DynamicMenu, ModuleSynchronous, Read, Wait or *. An option must be followed by a boolean argument bool. You can use commas to separate individual options.

If you set an option to "True", then when the corresponding command is run, fvwm displays the cursor of the WAIT context of the CursorStyle command. "False" forces it to not display the cursor. The default is:

BusyCursor DynamicMenu False, ModuleSynchronous False, \
Read False, Wait False

The * option refers to all available options. ๐Ÿ’ซ

  • The Read option controls the PipeRead command.
  • The DynamicMenu option affects the DynamicPopupAction and MissingSubmenuFunction options of the AddToMenu command. If this option is set to "False", then the busy cursor is not displayed during a dynamic menu command even if this command is a Read or PipeRead command and the Read option is set to "True".
  • The ModuleSynchronous option affects the ModuleSynchronous command. If this option is set to "False", then the busy cursor is not displayed while fvwm waits for a module started by ModuleSynchronous to complete its startup.
  • The Wait option affects only the root cursor. During a wait pause the root cursor is replaced by the busy cursor and fvwm is still fully functional (you can escape from the pause, see the EscapeFunc command). If you want to use this option and you don't use the default root cursor, you must set your root cursor with the CursorStyle command.

โœจ ClickTime [delay] โœจ

Specifies the maximum delay in milliseconds between a button press and a button release for the Function command to consider the action a mouse click. The default delay is 150 milliseconds. Omitting the delay value resets the ClickTime to the default. โฑ๏ธ

ClickTime also specifies the delay between two clicks to be interpreted as a double-click. periodt.


โœจ ColormapFocus FollowsMouse | FollowsFocus โœจ

By default, fvwm installs the colormap of the window that the cursor is in. If you use

ColormapFocus FollowsFocus

then the installed colormap is the one for the window that currently has the keyboard focus. slay. ๐ŸŒˆ


โœจ CursorStyle context [num | name | None | Tiny | file [x y] [fg bg]] โœจ

Defines a new cursor for the specified context. Heads up bestie: this command can not control the shapes an application uses, for example to indicate that it's busy. ๐Ÿ˜Œ

The various contexts are:

  • POSITION (top_left_corner) โ€” used when initially placing windows
  • TITLE (top_left_arrow) โ€” used in a window title-bar
  • DEFAULT (top_left_arrow) โ€” used in windows that do not set their cursor
  • SYS (hand2) โ€” used in one of the title-bar buttons
  • MOVE (fleur) โ€” used when moving or resizing windows
  • RESIZE (sizing) โ€” used when moving or resizing windows
  • WAIT (watch) โ€” used during certain fvwm commands (see BusyCursor for details)
  • MENU (top_left_arrow) โ€” used in menus
  • SELECT (crosshair) โ€” used when the user is required to select a window
  • DESTROY (pirate) โ€” used for Destroy, Close, and Delete commands
  • TOP (top_side) โ€” used in the top side-bar of a window
  • RIGHT (right_side) โ€” used in the right side-bar of a window
  • BOTTOM (bottom_side) โ€” used in the bottom side-bar of a window
  • LEFT (left_side) โ€” used in the left side-bar of a window
  • TOP_LEFT (top_left_corner) โ€” used in the top left corner of a window
  • TOP_RIGHT (top_right_corner) โ€” used in the top right corner of a window
  • BOTTOM_LEFT (bottom_left_corner) โ€” used in the bottom left corner of a window
  • BOTTOM_RIGHT (bottom_right_corner) โ€” used in the bottom right corner of a window
  • TOP_EDGE (top_side) โ€” used at the top edge of the screen
  • RIGHT_EDGE (right_side) โ€” used at the right edge of the screen
  • BOTTOM_EDGE (bottom_side) โ€” used at the bottom edge of the screen
  • LEFT_EDGE (left_side) โ€” used at the left edge of the screen
  • ROOT (left_ptr) โ€” used as the root cursor

The defaults are shown in parentheses above. If you ever want to restore the default cursor for a specific context you can just omit the second argument. ๐Ÿ’–

The second argument is either the numeric value of the cursor as defined in the include file X11/cursorfont.h or its name (without the XC_ prefix). Alternatively, the xpm file name may be specified. The name can also be None (no cursor) or Tiny (a single pixel as the cursor).

# make the kill cursor be XC_gumby (both forms work):
CursorStyle DESTROY 56
CursorStyle DESTROY gumby

Alternatively, the cursor can be loaded from an (XPM, PNG or SVG) image file. If fvwm is compiled with Xcursor support, full ARGB is used, and (possibly animated) cursor files made with the xcursorgen program can be loaded. Otherwise the cursor is converted to monochrome. ๐ŸŒธ

The optional x and y arguments (following a file argument) specifies the hot-spot coordinate with 0 0 as the top left corner of the image. Coordinates within the image boundary are valid and override any hot-spot defined in the (XPM/Xcursor) image file. An invalid or undefined hot-spot is placed in the center of the image.

CursorStyle ROOT cursor_image.png 0 0

The optional fg and bg arguments specify the foreground and background colors for the cursor, defaulting to black and white (reverse video compared to the actual bitmap). These colors are only used with monochrome cursors. Otherwise they are silently ignored. ๐Ÿ’€

CursorStyle ROOT nice_arrow.xpm yellow black

โœจ DefaultFont [fontname] โœจ

DefaultFont sets the default font to font fontname. The default font is used by fvwm whenever no other font has been specified. To reset the default font to the built-in default, just omit the argument. ๐Ÿ‘‘

The default font is used for menus, window titles, icon titles as well as the geometry feedback windows during a move or resize operation. To override the default font in a specific context, use the Style * Font, Style * IconFont, or MenuStyle commands. ๐ŸŽ€


โœจ DefaultIcon filename โœจ

Sets the default icon which is used if a window has neither a client-supplied icon nor an icon supplied via the Icon option of the Style command. ๐Ÿ’œ

DefaultLayers bottom put top

okay so this one changes up the layers that the StaysOnBottom, StaysPut and StaysOnTop Style options use. Initially, the layers 2, 4 and 6 are the ones in play. ๐Ÿ’…


Deschedule [command_id]

Bestie, this yanks every command that was scheduled with the id command_id via the Schedule command right out of the list of commands to be executed โ€” unless they already ran, in which case, too late, they've lived their life. ๐Ÿ™ˆ If command_id is left out, the value of the variable $[schedule.last] gets used as the id.


Emulate Fvwm | Mwm | Win

This is the catch-all for how fvwm does all the ~miscellaneous~ little things. rn it's in charge of where the move/resize feedback window shows up, and how window placement gets aborted. Wanna feel more Mwm- or Win-ish? Call Emulate with Mwm or Win as the argument. With Mwm, the resize and move feedback windows sit in the center of the screen, instead of the upper left corner. It also changes how manual placement is aborted โ€” go peek at the ManualPlacement description for that tea. ๐Ÿ“


EscapeFunc

By default, the key sequence Ctrl-Alt-Escape is your escape hatch โ€” literally โ€” from a Wait pause and from a locked ModuleSynchronous command. EscapeFunc used together with the Key command is how you configure that key sequence. Example:

Key Escape A MC -
Key Escape A  S EscapeFunc

That replaces the Ctrl-Alt-Escape key sequence with Shift-Escape for aborting a Wait pause and ModuleSynchronous command. And heads up: EscapeFunc used outside the Key command does absolutely nothing. ๐Ÿ™ˆ


FakeClick [command value] ...

Mainly for debugging fvwm, and no cap โ€” no guarantees are made that it works for you. FakeClick can simulate mouse button press and release events and pass them to fvwm or to the applications. The parameters are a list of commands made of pairs of command tokens and integer values. The press and release commands are followed by the appropriate mouse button number and generate a button press or release event on the window below the pointer. The wait command pauses fvwm for the given number of milliseconds. The modifiers command simulates pressing or releasing modifier keys โ€” the values 1 to 5 are mapped to Mod1 to Mod5, while 6, 7 and 8 are mapped to Shift, Lock and Control. The modifier is set for any further button events. To release a modifier key, use the corresponding negative number. The depth command determines which window the button events get sent to. With a depth of 1, all events go to the root window, regardless of the pointer's position. With 2, the event is passed to the top level window under the pointer, which is usually the frame window. With 3, events go to the client window. Higher numbers go to successive sub windows. Zero (0) goes to the smallest window that contains the pointer. Note that events propagate upward. โญ

FakeClick depth 2 press 1 wait 250 release 1

That simulates a click with button 1 in the parent window (depth 2) with a delay of 250 milliseconds between the press and the release. Note: all command names can be abbreviated with their first letter.


FakeKeypress [command value] ...

Also mainly for debugging fvwm, also no guarantees, fr fr. FakeKeypress can simulate key press and release events and pass them to fvwm or applications. The parameters are a list of commands made of pairs of command tokens and values. The press and release commands are followed by a key name. The key name is a standard X11 key name as defined in /usr/include/X11/keysymdef.h, (without the XK_ prefix), or the keysym database /usr/X11R6/lib/X11/XKeysymDB. The wait, modifiers and depth commands are the same as the ones used by FakeClick.

Save all GVim sessions with: "Esc:w\n"

All (gvim) FakeKeypress press Escape \
                  press colon \
                  press w \
                  press Return

Save & exit all GVim sessions with: "Esc:wq\n"

All (gvim) FakeKeypress press Escape \
                  press colon \
                  press w \
                  press q \
                  press Return

Send A to a specific window:

WindowId 0x3800002 FakeKeypress press A

Note: all command names can be abbreviated with their first letter. ๐Ÿ‘‘


ImagePath path

Specifies a colon separated list of directories to search for images in (both monochrome and pixmap, bestie). To find an image given by a relative pathname, fvwm looks into each directory listed, in turn, and uses the first file it finds. ๐ŸŽ€

If a directory is given in the form "/some/dir;.ext", that means every image in that directory has the extension ".ext" that should be forced. The original image name (which may contain another extension, or no extension at all) is not probed โ€” instead ".ext" is added, or it replaces the original extension. Super useful if, say, a user has some image directories with ".xpm" images and other image directories with the same names but ".png" images.

The path may contain environment variables such as $HOME (or ${HOME}). And a '+' in the path is expanded to the previous value of the path, which lets you append or prepend to the path easily.

For example:

ImagePath $HOME/icons:+:/usr/include/X11/bitmaps

LocalePath path

Specifies a colon separated list of "locale path" to search for string translations in. A locale path is made up of a directory path and a text domain, separated by a semicolon (';'). As an example, the default locale path is:

/install_prefix/share/locale;fvwm

where install_prefix is the fvwm installation directory. With a locale path like that, translations are searched for in

/install_prefix/share/locale/lang/LC_MESSAGES/fvwm.mo

where lang depends on the locale. If no directory is given, the default directory path is assumed. If no text domain is given, fvwm is assumed. Without an argument, the default locale path is restored. โœจ

Same as the ImagePath command: path may contain environment variables and a '+' to append or prepend the locale path easily.

For example, the fvwm-themes package uses

LocalePath ";fvwm-themes:+"

to add locale catalogs.

The default fvwm catalog contains a few strings used by the fvwm executable itself (Desk and Geometry) plus strings used in some default configuration files and FvwmForm configuration. You can take a look at the po/ subdirectory of the fvwm source to get the list of the strings with a possible translation in various languages. At present, very few languages are supported. ๐Ÿ˜ญ

The main use of locale catalogs is via the "$[gt.string]" parameter:

DestroyMenu MenuFvwmWindowOps
AddToMenu   MenuFvwmWindowOps "$[gt.Window Ops]" Title
+ "$[gt.&Move]"              Move
+ "$[gt.&Resize]"            Resize
+ "$[gt.R&aise]"             Raise
+ "$[gt.&Lower]"             Lower
+ "$[gt.(De)&Iconify]"       Iconify
+ "$[gt.(Un)&Stick]"         Stick
+ "$[gt.(Un)Ma&ximize]"      Maximize
+ "" Nop
+ "$[gt.&Close]"             Close
+ "$[gt.&Destroy]"           Destroy

which gives a menu in the locale languages, if translations are available. ๐Ÿซถ

Note that the FvwmScript module has a set of special instructions for string translation. Explaining how to build locale catalogs is out of the scope of this discussion, so please refer to the GNU gettext documentation.


PrintInfo subject [verbose]

Prints information on subject to the debug log file, which defaults to $HOME/.fvwm/fvwm3-output.log. The environment variables $FVWM_USERDIR and $FVWM3_LOGFILE can alter this default. For this logfile to be written, either fvwm3 has to be started with the -v option, or the SIGUSR2 signal can be used to toggle opening/closing the debug log file.

ngl, the original literally repeats this next paragraph in the weirdest way, so I'm reproducing it faithfully instead of pretending it isn't there ๐Ÿ’€ โ€” An optional integer argument to debug log file, which defaults to $HOME/.fvwm/fvwm3-output.log. Environment variables $FVWM_USERDIR and $FVWM3_LOGFILE can alter this default. For this logfile to be written, either fvwm3 has to be started with -v option or SIGUSR2 signal can be used to toggle opening/closing debug log file.

An optional integer argument verbose defines the level of information that's given. The current valid subjects are:

  • Colors โ€” prints information about the colors used by fvwm. Super useful on screens that can only display 256 (or less) colors at once. If verbose is one or greater, the palette used by fvwm is printed. If you have a limited color palette and you run out of colors, this command might be helpful.
  • ImageCache โ€” prints information about the images loaded by fvwm. If verbose is one or greater, all images in the cache will be listed together with their respective reuse.
  • Locale โ€” prints information on your locale and the fonts that fvwm used. verbose can be 1 or 2.
  • nls โ€” prints information on the locale catalogs that fvwm used.
  • bindings โ€” prints information on all the bindings fvwm has: key and mouse bindings. verbose has no effect with this option.
  • infostore โ€” prints information on all entries in the infostore, listing the key and its value. verbose has no effect with this option.

Schedule [Periodic] delay_ms [command_id] command

The command is executed after about delay_ms milliseconds. This may be useful in some tricky setups, lowkey. The command is executed in the same context window as the Schedule command. An optional integer argument command_id may be given in decimal, hexadecimal or octal format. That id can be used with the Deschedule command to remove the scheduled command before it gets executed. If no id is given, fvwm uses negative id numbers, starting with -1 and decreasing by one with each use of the Schedule command. Note that the Schedule command and its arguments undergo the usual command line expansion, and, when command is finally executed, it is expanded again. It may therefore be necessary to quote the parts of the command that must not be expanded twice. ๐Ÿ’€

Note: a window's id as it is returned with $[w.id] can be used as the command_id. Example:

Current Schedule 1000 $[w.id] WindowShade

The Schedule command also supports the optional keyword Periodic, which indicates that the command should be executed every delay_ms. Example:

           Schedule Periodic 10000 PipeRead '[ -N "$MAIL" ] && echo \
            Echo You have mail'

Bestie, when you wanna stop that little looping situation, you hit it with Deschedule. That's it, that's the whole vibe. ๐Ÿ’…

  • State state [bool] โ€” Sets, clears, or toggles one of the 32 user defined states that every single window carries around with it. The state is a number from 0 to 31. Lowkey, fvwm does not care what these states mean โ€” they're yours, they're just vibes. But you can check them in conditional commands like Next using the State condition. The optional bool arg is a boolean argument: "True" sets the state, "False" clears it, and "toggle" flips it to the opposite. If you don't give bool at all, the state just gets toggled. Simple as. โœจ
  • WindowList [(conditions)] [position] [options] [double-click-action] โ€” Pops up (like, literally pops it up) a menu showing the title and geometry of every window currently chillin' on the desktop. ๐Ÿ‘‘

The geometry format goes like this: desk(layer): x-geometry sticky โ€” where desk and layer are the corresponding numbers, and sticky is either empty or a capital S. If a window is iconified, its geometry shows up in parentheses. Clicking an item from the window list pop-up menu runs the interpreted function "WindowListFunc", with that window's id passed in as $0. The default "WindowListFunc" looks exactly like this:

    AddToFunc WindowListFunc
    + I Iconify off
    + I FlipFocus
    + I Raise
    + I WarpToWindow 5p 5p

If those defaults aren't giving, you can absolutely destroy the built-in "WindowListFunc" and write your own. Main character behavior, honestly.

The window list menu uses the "WindowList" menu style if it's defined (peep the MenuStyle command for that). Otherwise it just uses the default menu style. Wanna go back to the default? Issue this:

    DestroyMenuStyle WindowList

Example, because examples slay:

    MenuStyle WindowList SelectOnRelease Meta_L

So โ€” the conditions let you exclude certain windows from the list. Go read the Current command for the deets. Only windows matching the given conditions show up in the window list. The options below work the other way around: windows that would otherwise not be included can be selected with them. And heads up โ€” the conditions always override the options. No cap. ๐Ÿซถ

The position arguments are the same as for Menu. The double-click-action command gets invoked if the user double-clicks (or hits the key rapidly twice if the menu is bound to a key) while bringing up the window list. And it must be quoted if it's more than one word.

The double-click-action is genuinely useful for defining a default window if you've bound the window list to a key (or button) like this:

    # Here we call an existing function, but
    # it may be different.  See the default
    # WindowListFunc definition earlier in this
    # man page.
    AddToFunc SwitchToWindow
    + I WindowListFunc

    Key Tab A M WindowList "Prev SwitchToWindow"

So hitting Alt-Tab once brings up the window list, and if you hit it twice, focus flips between the current window and the last focused one. With the proper SelectOnRelease menu style (see that example above ๐Ÿ‘†), a window is selected as soon as you release the Alt key. Obsessed.

The options you can pass to WindowList are separated by commas, and they go: Geometry / NoGeometry / NoGeometryWithInfo, NoDeskNum, NoLayer, NoNumInDeskTitle, NoCurrentDeskTitle, MaxLabelWidth width, TitleForAllDesks, Function funcname, Desk desknum, CurrentDesk, NoIcons / Icons / OnlyIcons, NoNormal / Normal / OnlyNormal, NoSticky / Sticky / OnlySticky, NoStickyAcrossPages / StickyAcrossPages / OnlyStickyAcrossPages, NoStickyAcrossDesks / StickyAcrossDesks / OnlyStickyAcrossDesks, NoOnTop / OnTop / OnlyOnTop, NoOnBottom / OnBottom / OnlyOnBottom, Layer m [n], UseSkipList / OnlySkipList, NoDeskSort, ReverseOrder, CurrentAtEnd, IconifiedAtEnd, UseIconName, Alphabetic / NotAlphabetic, SortByResource, SortByClass, NoHotkeys, SelectOnRelease ,ShowPage, ShowPageX, ShowPageY, ShowScreen.

(Note โ€” normal means not iconic, sticky, or on top)

With the SortByResource option, windows are sorted alphabetically first by resource class, then by resource name, and then by window name (or icon name if UseIconName is specified). ReverseOrder also works exactly the way you'd expect it to. ๐Ÿฆ‹

With the SortByClass option, windows are sorted just like with SortByResource, except the resource name is not taken into account โ€” only the resource class.

The SelectOnRelease option works exactly like the MenuStyle option with the same name, but it overrides whatever option was given in a menu style. By default, this option is set to the left key. To switch it off, use SelectOnRelease without a key name.

If you pass in a function via Function funcname, it gets called within a window context of the selected window:

    AddToFunc IFunc I Iconify toggle
    WindowList Function IFunc, NoSticky, CurrentDesk, NoIcons

If you use the Layer m [n] option, only windows in layers between m and n are displayed. n defaults to m. And with the ReverseOrder option, the order of the windows in the list is reversed.

With the CurrentAtEnd option, the currently focused window (if there is one) is shown at the bottom of the list. This is mostly intended for simulating that Alt-Tab behavior from another GUI.

IconifiedAtEnd makes iconified windows get moved to the end of the list. Also from another GUI. Copying homework but changing it slightly, iconic honestly. ๐Ÿ’€

The NoGeometry option makes fvwm not display the geometries โ€” and the separators that indicate the different desktops. NoGeometryWithInfo removes the geometries but keeps the desktop information, and indicates iconic windows. NoDeskNum makes fvwm not display the desktop number in the geometry, or before the window title when combined with the NoGeometryWithInfo option. NoNumInDeskTitle is only useful if a desktop name is defined with the DesktopName command โ€” it makes fvwm not display the desktop number before the desktop name. By default, the WindowList menu has a title that indicates the current desk, or the selected desktop if the Desk condition is used. The NoCurrentDeskTitle option removes this title. TitleForAllDesks makes fvwm add a menu title with the desk name and/or number before each group of windows on the same desk. With NoLayer, the layer of the window is not displayed. The options ShowPage, ShowPageX and ShowPageY enable displaying the page of the window rounded to multiples of the display size. With ShowScreen, the window's screen name is displayed.

The MaxLabelWidth option takes the number of characters to print as its argument. No more than that many characters of the window name are visible. Periodt.

So if you wanted to use the WindowList as an icon manager, you could invoke this:

    WindowList OnlyIcons, Sticky, OnTop, Geometry
(Note โ€” the Only options essentially wipe out all the other onesโ€ฆ except the OnlyListSkip option, which just causes WindowList to only consider the windows with the WindowListSkip style.)
  • XSync โ€” When XSync is called, the X function with the same name is used to send all pending X requests to the server. Bestie, this command is intended for debugging only. ๐Ÿ™ˆ
  • XSynchronize [bool] โ€” The XSynchronize command controls whether X requests are sent to the X server immediately or not. Normally, requests are sent in bigger batches to save unnecessary communication. To send requests immediately, use "True" as the argument; to disable that, use "False"; or to toggle between both methods, use "Toggle" or just omit the bool argument. Fvwm defaults to synchronized requests when started with the --debug option. This command is intended for debugging only. ๐Ÿ”ฅ
  • + โ€” Used to keep adding to the last specified decor, function, or menu. Go read the discussion for AddToDecor, AddToFunc, and AddToMenu.

๐ŸŒˆ Window Movement and Placement ๐ŸŒˆ

  • AnimatedMove x y [Warp] โ€” Moves a window in an animated fashion. Basically like the Move command. The options are the same, except they are required, because it genuinely doesn't make sense to have a user move the window both interactively and animatedly. If you specify the optional argument Warp, the pointer gets warped along with the window. ๐Ÿงš
  • GeometryWindow Hide | Show | Colorset n | Position x y | Screen S โ€” Configures the position or size window that's usually shown when you move or resize a window interactively. You can use this to hide it, show it, change the colorset, change the location, or change the screen of the geometry window. Multiple options can be set at once, separated by spaces. Details of each option are right below. ๐Ÿ’–
    • GeometryWindow Hide [ Never | Move | Resize ] โ€” Hides or switches off the geometry window. If you give the optional parameters Move or Resize, it will only hide the geometry window during the respective operation. The parameter Never switches the geometry back on again (equivalent to Show).
    • GeometryWindow Show [ Never | Move | Resize ] โ€” Shows or switches on the geometry window (equivalent to Hide Never). If you give the optional parameters Move or Resize, it will only show the geometry window during the respective operation. The parameter Never switches the geometry window off (equivalent to Hide).
    • GeometryWindow Colorset cset โ€” Sets the colorset of the geometry window to cset. Use the literal option default for cset to use the default colorset.
    • GeometryWindow Position [+|-]x[p] [+|-]y[p] โ€” Configures the position where the geometry window appears. x and y are the relative coordinates as a percentage of the screen size. If you provide a leading -, the coordinates are computed from the left/bottom of the screen respectively. If the coordinates are appended with a p, they're interpreted as the number of pixels from the respective screen edge. If no position arguments are given, the geometry window's position returns to its default state of the upper left corner โ€” or the center if emulating MWM. ๐Ÿ‘‘
    • GeometryWindow Screen RANDRNAME โ€” Configures which screen the geometry window is shown on. By default the geometry window is shown on the current screen. If a valid RANDRNAME is provided, the geometry window will always be shown on that screen. Use current as the RANDRNAME to return to the default.

Examples:

# Position the geometry window in the center of the screen
GeometryWindow Position 50 50
# Position the geometry window next to the RightPanel
GeometryWindow Position -120p 0
# Use colorset 2 for the geometry window
GeometryWindow Colorset 2
# Only show the geometry window on the primary monitor
GeometryWindow Screen $[monitor.primary]
# Hide the geometry window
GeometryWindow Hide

Layer ๐Ÿ’…

  • Layer [arg1 arg2] | [default] โ€” ok so bestie, this one literally just puts the current window in a new layer. If arg1 is non-zero, then the next layer is the current layer number plus arg1. If arg1 is zero, then the new layer is arg2. That's it, that's the whole vibe.

And there's a lil special case, as a treat: default puts the window in its default layer, i.e. the layer it was initially in. The same thing happens if no args, or invalid args, get specified. No drama. ๐Ÿซถ

Lower ๐ŸŒธ

  • Lower โ€” lets the user lower a window. Important tho, bestie: this lowers a window only in its layer. So if you wanna send it all the way to the absolute bottom of the pile, you need this iconic lil combo:
AddToFunc lower-to-bottom
 + I Layer 0 0
 + I Lower

Move โœจ

  • Move [options] โ€” allows the user to move a window. If it's called from somewhere in a window or its border, then that window is the one that moves. If it's called from the root window, then the user gets to select the target window. Move can be called with various options to either start an interactive move, specify the position to move, or a direction. Versatile queen. ๐Ÿ‘‘

Interactive move, no options ๐Ÿฆ‹

Move with no options starts an interactive move. The window may snap to other windows and screen boundaries โ€” configurable with the SnapAttraction style. And dragging a window to the edge of the screen can be used to drag it to other pages! (See EdgeScroll, and the EdgeMoveDelay style for more info, iykyk.)

Holding down Alt disables snapping and lets you switch pages with no delay at all. Interactive movement can be aborted with the Escape key or any mouse button that isn't set to place the window. By default, mouse button 2 is set to cancel the move operation. To change that, you may use the Mouse command with the special context 'P' for Placement.

The window condition PlacedByButton can be used to check if a specific button was pressed to place the window (see the Current command). ๐Ÿ’–

The pointer argument ๐ŸŽ€

If the single argument pointer is given, the top left corner of the window is moved to the pointer position before starting an interactive move. This is mainly intended for internal use by modules like FvwmPager.

Move pointer

Shuffle move ๐ŸŒˆ

To move a window in a given direction until it hits another window, icon, or screen boundary, use:

Move shuffle [options] _direction_(s)

The direction can be North/N/Up/U, East/E/Right/R, South/S/Down/D, or West/W/Left/L. The window will move in the given direction until it hits another window or the EwmhBaseStruts/screen boundary. When a window is at the EwmhBaseStruts/screen boundary, it will move to the next monitor in the given direction, if it exists. If a window is outside of the current working area (partly off screen), it will move to the edge of the working area. Windows will honor the EWMH working area and stop at the EwmhBaseStruts unless the literal option ewmhiwa is given. If multiple direction(s) are given, the window will move the directions in the order of the sequence stated.

The literal option Warp will warp the mouse pointer to the window. The literal option all_windows will consider all windows on the same monitor instead of just the windows in the path the window is moving โ€” this allows moving to the boundary of a window it is next to. The literal option both_sides will consider both the close side and the far side of the window (by default only the close side is considered).

If the literal option snap followed by a snap type of windows, icons, or same is given, then the window will only stop if it hits another window, icon, or the same type. If the literal option layers followed by two integers specifying a min layer and max layer is given, then only windows on the layers between min and max layers will stop the window. For example:

# Shuffle the window Right.
Move shuffle Right
# Shuffle Up, only consider windows on Layer 3.
Move shuffle layers 3 3 Up
# Shuffle Left then Up
Move shuffle Left Up
# Shuffle Up then Left (may not be same position as above)
Move shuffle Up Left

Moving to a specified position ๐Ÿ’œ

Move can be used to moved a window to a specified position:

Move [screen _S_] [desk _N_] [w | m | v]_x_[p | w] \
     [w | m | v]_y_[p | w] [Warp] [ewmhiwa]

This will move the window to the x and y position (see below). By default, the EWMH working area of each monitor is honoured (the working area for each monitor is set via EwmhBaseStruts and honors any strut hints provided by windows on the monitor). This means that if a window is placed outside the working area, the position of the window will be adjusted to fit inside the working area of the screen the center of the window is on. If the trailing option ewmhiwa is given, then the window position will ignore the working area and its position will not be adjusted (this option is needed to move windows off the screen and to have full control of where it is placed). If the option Warp is given then the pointer is warped to the window.

If the literal option screen followed by a RandR screen name S is specified, the coordinates are interpreted as relative to the given screen. The width and height of the screen are used for the calculations instead of the display dimensions. The screen is interpreted as in the MoveToScreen command.

If the literal option desk followed by a desk number N is specified, place the window on the specified desk after it has been moved. This can serve two purposes: first, you can move a window's position and desk in a single command. Second, when a window is moved between monitors, its desk is updated to be the same as the new monitor โ€” this option can override that behavior by specifying which desk the window should end up on. ๐Ÿซถ

The x and y positional args ๐Ÿงš

The positional arguments x and y can specify an absolute or relative position from either the left/top (positive values) or right/bottom (negative values) of the global screen (the bounding box that contains all monitors) or specified screen. By default, the numeric value given is interpreted as a percentage of the screen's width/height, but a trailing 'p' changes the interpretation to mean pixels, while a trailing 'w' means percent of the window width/height.

  • To move the window relative to its current position, add the 'w' (for "window") prefix before the x and/or y value.
  • To move the window to a position relative to the current location of the pointer, add the 'm' (for "mouse") prefix.
  • To move the window relative to the virtual screen coordinates, add the 'v' (for "virtual screen") prefix. This is mostly for internal use with FvwmPager, but can be used to give exact coordinates on the virtual screen and is best used with the 'p' suffix.

To leave either coordinate unchanged, "keep" can be specified in place of x or y. Periodt. ๐Ÿ’…

For advanced uses, the arguments x and y can be used multiple times, but without the prefix 'm' or 'w'. (See complex examples below.)

Simple examples โญ

# Interactive move
Mouse 1 T A Move
# Move window to top left is at (10%,10%)
Mouse 2 T A Move 10 10
# Move top left to (10pixels,10pixels)
Mouse 3 T A Move 10p 10p

More complex examples ๐Ÿ”ฅ

(These can be bound as actions to keystrokes, etc.; only the command is shown, though):

# Move window so bottom right is at bottom
# right of screen
Move -0 -0

# Move window so top left corner is 10 pixels
# off the top left screen edge
Move +-10 +-10

# Move window 5% to the right, and to the
# middle vertically
Move w+5 50

# Move window up 10 pixels, and so left edge
# is at x=40 pixels
Move 40p w-10p

# Move window to the mouse pointer location
Move m+0 m+0

# Move window to center of screen (50% of screen
# position minus 50% of widow size).
Move 50-50w 50-50w

See also the AnimatedMove command. ๐Ÿ’–

MoveToDesk ๐ŸŒธ

  • MoveToDesk [prev | arg1 [arg2] [min max]] โ€” moves the selected window to another desktop. The arguments are the same as for the GotoDesk command. Without any arguments, the window is moved to the current desk. Simple as. โœจ

MoveThreshold ๐ŸŽ€

  • MoveThreshold [pixels] โ€” so when the user presses a mouse button upon an object, fvwm waits to see if the action is a click or a drag. If the mouse moves by more than pixels pixels, it is assumed to be a drag.

Previous versions of fvwm hardwired pixels to 3, which is now the default value. If pixels is negative or omitted, the default value is restored โ€” "(which might be increased when 16000x9000 pixel displays become affordable)" ๐Ÿ˜ญ iconic footnote.

MoveToPage ๐Ÿฆ‹

  • MoveToPage [options] [x[p | w] y[p | w]] | [prev] โ€” moves the selected window to another page (x,y). The upper left page is (0,0), the upper right is (M,0), where M is one less than the current number of horizontal pages specified in the DesktopSize command. Similarly the lower left page is (0,N), and the lower right page is (M,N). Negative page numbers refer to pages from the rightmost/lowest page. If x and y are not given, the window is moved to the current page (a window that has the focus but is off-screen can be retrieved with this โ€” lowkey a lifesaver fr fr). Moving windows to a page relative to the current page can be achieved by adding a trailing 'p' after any or both numerical arguments. To move the window relative to its current location, add a trailing 'w'. To move a window to the previous page use prev as the single argument.

Windows are usually not moved beyond desk boundaries.

Possible options are wrapx and wrapy to wrap around the x or y coordinate when the window is moved beyond the border of the desktop. For example, with wrapx, when the window moves past the right edge of the desktop, it reappears on the left edge. The options nodesklimitx and nodesklimity allow moving windows beyond the desk boundaries in x and y direction (disabling the wrapx and wrapy options).

Examples:

# Move window to page (2,3)
MoveToPage 2 3

more MoveToPage content, since the last part cut off mid-example ๐Ÿ’…

# Move window to lowest and rightmost page
MoveToPage -1 -1

# Move window to last page visited
MoveToPage prev

# Move window two pages to the right and one
# page up, wrap at desk boundaries
MoveToPage wrapx wrapy +2p -1p
  • MoveToScreen [screen] โ€” yoinks the selected window over to another screen ๐Ÿฆ‹. The screen argument has to be a valid RandR name, bestie, no making them up.
  • OpaqueMoveSize [percentage] โ€” tells fvwm the biggest window it should move opaquely (you know, actual window sliding, not a sad little outline). percentage is percent of the total screen area, and yes it can be greater than 100, go off.
    • OpaqueMoveSize 0 โ†’ every window moves with the traditional rubber-band outline.
    • OpaqueMoveSize unlimited โ†’ or if a negative percentage is given, all windows move as solid windows. iconic.
    • the default is OpaqueMoveSize 5 โ†’ small windows get moved in an opaque manner, big ones get the rubber-band treatment. If percentage is omitted or invalid, the default value is set.
    • wanna resize windows opaquely? that's the ResizeOpaque style, see the Style command ๐Ÿ’–
  • PlaceAgain [Anim] [Icon] โ€” re-computes the current window's position using the initial window placement logic โœจ. The window moves to where it would've been if it were a brand-new window that just appeared. Most useful with Smart or Clever (ReallySmart) placement. Anim โ†’ an animated move puts the window in its new position. Icon โ†’ the icon gets placed again instead.
  • Raise โ€” lets the user raise a window ๐Ÿ™Œ. lowkey important: this raises a window only in its layer. To bring a window to the absolute top, use
AddToFunc raise-to-top
 + I Layer 0 ontop
 + I Raise

where ontop is the highest layer used in your setup.

  • RaiseLower โ€” alternately raises and lowers a window. It's raised if it's obscured by any window (except its own transients when the RaiseTransient style is used; see the Style command), otherwise it's lowered.
  • Resize [[frame] [direction dir] [warptoborder automatic] [fixeddirection] width[p | c | wa | da] height[p | c]] โ€” the resize girlie ๐Ÿ’…. Called from somewhere in a window or its border? then that window gets resized. Called from the root window? then the user gets to pick the target window.
    • Resize with no options starts an interactive resize, periodt.
    • if the EdgeResizeDelay style is set, or the Alt key is held down, the window can be resized across the edge of the screen.
    • abort it with the Escape key, or by pressing any mouse button โ€” except button 1, which confirms it.
    • give the optional width and height and the window gets resized so its dimensions are width by height. Units are percent-of-screen, unless a p is tacked onto one or both coordinates, in which case it's pixels. A c suffix โ†’ the unit defined by the client application (hence the c). A wa suffix โ†’ the value is a percentage of the width or height size of the EWMH working area. A da suffix โ†’ percentage of the width or height of the EWMH dynamic working area. so like:
Resize 80c 24c

to make a terminal window just big enough for 80x24 characters ๐Ÿซถ

  • prefix width or height with w and the size isn't absolute anymore, it gets added to the current size of the window:
# Enlarge window by one line
Resize keep w+1c
  • both width and height can be negative โ€” then the new size is the screen size minus the given value. If either value is "keep", the corresponding dimension of the window is left untouched. The new size is the size of the client window, so Resize 100 100 may make the window bigger than the screen ๐Ÿ˜ญ. To base the new size on the whole fvwm window instead, add the frame option after the command.
  • fixeddirection, direction and warptoborder are only used in interactive move operations. fixeddirection โ†’ the same border is moved even if the pointer moves past the opposite border. direction has to be followed by a direction name such as "NorthWest", "South" or "East" (you get the idea), and resizing starts immediately, even if the pointer isn't on a border. If the special option automatic is given as the direction argument, the direction to resize is calculated from the position of the pointer in the window โ€” and if the pointer is in the middle of the window, no direction is calculated. warptoborder warps the pointer to the direction indicated; same energy, the border to warp to is calculated from the pointer's proximity to a given border. Also, if resizing was started by clicking on the window border, the pointer is warped to the outer edge of the border.
AddToFunc ResizeSE I Resize Direction SE
Mouse 3 A M ResizeSE
  • Resize [bottomright | br x y] โ€” alternate syntax era ๐ŸŒˆ, used when the keyword bottomright, or br for short, follows the command name. Then x and y specify the desired position of the bottom right corner of the window, interpreted exactly like the x and y arguments of the Move command. Actually, any of the options accepted by the Move command can be used. iykyk.
  • ResizeMaximize [resize-arguments] โ€” Resize x Maximize crossover episode โœจ. Used on a maximized window: the window is resized and is still in the maximized state afterwards. Used on an unmaximized window: the window is resized and put into the maximized state afterwards. Super useful if the user wants to resize the window temporarily and then return to the original geometry. The resize-arguments are the same as for Resize.
  • ResizeMove resize-arguments move-arguments โ€” does the same as the Resize and Move commands, but in one single call, which is less visually disturbing ๐ŸŽ€. The resize-arguments are exactly the same as for Resize, and the move-arguments are exactly the same as for Move โ€” except the pointer option, which ResizeMove does not support.
# Move window to top left corner and cover
# most of the screen
ResizeMove -10p -20p 0 0

# Grow the focused window towards the top of screen
Current Resize keep w+$[w.y]p keep 0
Note: Fvwm may not be able to parse the command properly if the bottomright option of the Resize command is used. heads up bestie ๐Ÿ’€
  • ResizeMoveMaximize resize-arguments move-arguments โ€” ResizeMove x Maximize, the sequel ๐Ÿ”ฅ. Used on a maximized window: the window is resized and moved and is still in the maximized state afterwards. Used on an unmaximized window: the window is resized and put into the maximized state afterwards. Useful if the user wants to resize the window temporarily and then return to the original geometry. The resize-arguments and move-arguments are the same as for the ResizeMove command.
  • RestackTransients โ€” regroups the transients of a window close to it in the stacking order, as if the window had just been lowered and then raised ๐Ÿฆ‹. The position of the window itself is not altered. Only windows that use either the RaiseTransient or LowerTransient style are affected at all. And when RestackTransients is used on a transient window with the StackTransientParent style set, it's redirected to the parent window.
  • SetAnimation milliseconds-delay [fractions-to-move-list] โ€” sets the time between frames and the list of fractional offsets that customize the animated moves of the AnimatedMove command and the animation of menus (if the menu style is set to animated; see the MenuStyle command) ๐Ÿงš. Omit the fractions-to-move-list and only the time between frames is altered. The fractions-to-move-list specifies how far the window should be offset at each successive frame, as a fraction of the difference between the starting location and the ending location. e.g.:
SetAnimation 10 -.01 0 .01 .03 .08 .18 .3 \
.45 .6 .75 .85 .90 .94 .97 .99 1.0

that sets the delay between frames to 10 milliseconds, and sets the positions of the 16 frames of the animation motion. Negative values are allowed, and are lowkey iconic for making the motion more cartoonish โ€” you briefly move slightly in the opposite direction of the main motion. those settings above are the default, no cap.

  • XorPixmap [pixmap] โ€” picks the pixmap with which bits are xor'ed when doing rubber-band window moving or resizing ๐Ÿ’ซ. Better odds of making the rubber-band visible if XorValue isn't giving good results. An example pixmap resize.rainbow.xpm is provided with the icon distribution ๐ŸŒˆ. To turn XorPixmap off again, use the XorValue command or just omit the pixmap argument.
  • XorValue [number] โ€” changes the value with which bits are xor'ed when doing rubber-band window moving or resizing. Valid values range from zero to the maximum value of an unsigned long integer on your system. Setting this value is a whole trial-and-error process ๐Ÿ™ˆ. The default value 0 tries to find a value that gives a good contrast to black and white. That default value is used if the given number is omitted or invalid.

๐Ÿ’– Focus & Mouse Movement ๐Ÿ’–

  • CursorBarrier [destroy] [options] [left top right bottom] โ€” a cursor barrier is a box that the cursor cannot be moved outside of ๐Ÿ‘‘ (unless it's warped with CursorMove or WarpToWindow). The left, top, right and bottom values give the percent distance the box is placed from each of the corresponding edges of the desktop. If the values end with a p, they're interpreted as pixel amounts instead. If the coords option is given, the values are interpreted as the left/top and right/bottom coordinates of the box's corners. If the screen RandRname option is given, the positions are computed relative to the specified monitor โ€” and screen c places the barrier on the current monitor.

Okay bestie, so you can stack multiple barriers just by calling CursorBarrier more than once. That's how you build yourself a whole lil collection of regions to trap the cursor in โ€” like one per monitor in a multi-monitor setup ๐Ÿ’– โ€” and then you use CursorMove or WarpToWindow to hop the cursor from barrier to barrier like it's crossing a border. No cap.

If the destroy command is in there, all the barriers get destroyed and the mouse is free to roam again ๐Ÿฆ‹. But if destroy is followed by an integer N, only that barrier gets destroyed โ€” and heads up, barriers are numbered in the order they were created, starting at 0. If the integer is negative, it counts backwards: -1 is the most recently created barrier, -2 is the second most recent, and so on ๐ŸŽ€. And when a barrier gets destroyed, all the barriers after it get renumbered. So in practice, the move is destroy -1 โ€” that nukes the most recent barrier without touching any of the earlier ones. Periodt. ๐Ÿ’…

By default the key binding ctrl+shift+D destroys all cursor barriers by calling CursorBarrier destroy ๐ŸŒธ.

Here are some examples, bestie:

# A barrier 15% from left/right and 10% from top/bottom.
CursorBarrier 15 10 15 10

# A barrier to confine the mouse to the current monitor.
CursorBarrier screen c

# A barrier to confine the mouse to a selected window
Pick CursorBarrier coords $[w.x]p $[w.y]p \
    $[math.+.$[w.x],$[w.width]]p $[math.+.$[w.y],$[w.height]]p

# Destroy all barriers
CursorBarrier destroy
Important bestie: if the CURSOR_BARRIER limit gets hit, all defined CursorBarriers become undefined ๐Ÿ˜ญ. In practice this is lowkey unlikely to ever happen tho. But if it does, a message gets printed to fvwm3's debug logs.

Also CursorBarrier only works if fvwm is compiled with the XFixes extension ๐Ÿซถ.


  • CursorMove [screen RANDRNAME] horizontal[p] vertical[p] โ€” the cursor teleporter โœจ

Without the screen option, CusorMove moves the mouse cursor a horizontal distance and a vertical distance from wherever it's currently sitting ๐Ÿ‘€. The values are either a percent of the virtual desktop size, or a pixel distance if you slap a 'p' on the end. Either one โ€” or both โ€” can be negative. For example:

# Move down and right by one full page.
CursorMove 100 100

# Move down two full pages.
CursorMove 0 200

# Move half page right and quarter page up.
CursorMove 50 -25

# Move left 100 pixels and down 50 pixels.
CursorMove -100p 50p

If you include the screen option followed by a valid RandR monitor name, CursorMove will move the cursor to the absolute position (starting at the top left corner, iykyk) given by the arguments โ€” either as percent values of the monitor's size, or as an absolute location with the 'p' suffix ๐Ÿ’–. Like:

# Move cursor to center of monitor DP-1
CursorMove screen DP-1 50 50

# Move cursor to the exact location (400, 200) of monitor DP-2
CursorMove screen DP-2 400p 200p

When you're moving to a specified screen, the horizontal and vertical values always get shifted to be inside the current page of that specified monitor. So for instance '50', '150', and '-150' all land on the center of the monitor, and none of them change the monitor's page. If you wanna change the page of a specified monitor, use GotoPage for that ๐ŸŽ€. Negative values can be used to specify distance from the right/bottom corner of the monitor.

CusorMove can only move the cursor relative to its current position, or to an absolute position on a given monitor ๐Ÿฆ‹. To move the cursor relative to a window, use WarpToWindow.

  • FlipFocus [NoWarp] โ€” runs a Focus command as if the user had used the pointer to select the window ๐Ÿ–ฑ๏ธโœจ. This command changes the order of the WindowList the exact same way clicking in a window to focus does โ€” aka the target window gets removed from the WindowList and plopped at the start ๐Ÿ‘‘. This one is recommended for use with the Direction command and in the function invoked from WindowList.
  • Focus [NoWarp] โ€” sets the keyboard focus to the selected window ๐ŸŒธ. If the NoWarp argument is given, that's literally all it does, that's the whole thing. Otherwise it also moves the viewport or window as needed to make the selected window visible ๐Ÿ‘€. Note that this command does not automatically raise the window. It does not warp the pointer into the selected window (peep the WarpToWindow function for that). It does not de-iconify. And this command does not alter the order of the WindowList โ€” instead it rotates the WindowList around so that the target window is at the start ๐Ÿ’ซ.
Heads up: when the NoWarp argument is given, Focus cannot transfer the keyboard focus to windows on other desks ๐Ÿ’€.

To raise and/or warp a pointer to a window together with Focus or FlipFocus, use a function, like this:

AddToFunc SelectWindow
+ I Focus
+ I Iconify false
+ I Raise
+ I WarpToWindow 50 8p
  • WarpToWindow [!raise | raise] x[p] y[p] โ€” warps the cursor to the associated window and raises it (unless the option !raise is present) ๐Ÿฆ‹โœจ. The parameters x and y default to percentage of window down and in from the upper left hand corner โ€” or number of pixels down and in if 'p' is appended to the numbers ๐ŸŽ€. If a number is negative, the opposite edge is used and the direction is reversed. This command also works with windows that aren't managed by fvwm ๐Ÿ‘€. In that case fvwm does not bring the window onto the screen if it isn't visible. For example, it's possible to warp the pointer to the center of the root window:
WindowId root WarpToWindow 50 50

๐Ÿ‘‘ Window State ๐Ÿ‘‘

  • Close โ€” if the window accepts the delete window protocol, a message gets sent to the window asking it to gracefully remove itself ๐Ÿซถ. If the window does not understand the delete window protocol, then the window gets destroyed as with the Destroy command ๐Ÿ’€. Note: if the window accepts the delete window protocol but doesn't close itself in response, the window is not deleted. That's just how it is, bestie.
  • Delete โ€” sends a message to a window asking that it remove itself, which frequently causes the application to exit โœจ.
  • Destroy โ€” destroys an application window, which usually causes the application to crash and burn ๐Ÿ”ฅ๐Ÿ’€. Dramatic, but that's literally what it says.
  • Iconify [bool] โ€” iconifies a window if it isn't already iconified, or de-iconifies it if it is already iconified ๐ŸŽ€. The optional argument bool is a boolean argument. "True" means only iconification is allowed, while "False" forces de-iconification. Using "toggle" switches between iconified and de-iconified states ๐Ÿฆ‹.

There are a bunch of Style options that influence the appearance and behavior of icons (e.g. StickyIcon, NoIcon) ๐Ÿ’….

For backward compatibility, the optional argument may also be a positive number instead of "True", or a negative number instead of "False". But ngl, note that this syntax is obsolete and will be removed in the future ๐Ÿ‘‹.

  • Maximize [flags] [bool | forget] [horizontal[p]] [vertical[p]] โ€” okay this one is the main character fr fr โœจ

Without its optional arguments (or if the bool bit has the value "toggle"), Maximize causes the window to alternately switch from a full-screen size to its normal size ๐Ÿ”„. To force a window into maximized (normal) state, you can use a "True" or "False" value for the bool argument.

With just the parameter "forget", a maximized window reverts back into normal state but keeps its current maximized size ๐Ÿ‘€. This can be useful in conjunction with the commands ResizeMaximize and ResizeMoveMaximize. If the window is not maximized, nothing happens.

With the optional arguments horizontal and vertical, which are expressed as percentage of a full screen, you can control the new size of the window ๐ŸŽ€. An optional suffix 'p' can be used to indicate pixels instead of percents of the screen size. If horizontal is greater than 0, then the horizontal dimension of the window is set to horizontal*screen_width/100. If the value is smaller than 0, the size is subtracted from the screen width โ€” so -25 is the same as 75 ๐Ÿง . If horizontal is "grow", it's maximized to the current available space until it finds any obstacle. The vertical resizing is similar. If both horizontal and vertical values are "grow", it expands vertically first, then horizontally, to find space ๐ŸŒธ. Instead of the horizontal "grow" argument, "growleft" or "growright" can be used โ€” respectively "growup" and "growdown" for vertical.

The optional flags argument is a space separated list containing the following key words: fullscreen, ewmhiwa, growonwindowlayer, growonlayers, keepgrowing, all_windows, both_sides, and screen ๐Ÿ‘‘.

  • fullscreen causes the window to become fullscreened if the appropriate EWMH hint is set.
  • ewmhiwa causes fvwm to ignore the EWMH working area.
  • growonwindowlayer causes the various grow methods to ignore windows with a layer other than the current layer of the window which is maximized.
  • The growonlayers option must have two integer arguments. The first one is the minimum layer and the second one the maximum layer to use. Windows that are outside of this range of layers are ignored by the grow methods ๐Ÿšซ. A negative value as the first or second argument means to assume no minimum or maximum layer.
  • The all_windows option will consider all windows on the same monitor in the direction the window is growing ๐Ÿ‘€. This can be used to grow a window to the edge of a window it's next to.
  • The option both_sides will consider both sides of other windows when growing (by default only the close side is considered). This can be used to grow a window to the boundaries of a window it's currently inside of ๐Ÿ’ซ.
  • keepgrowing will allow the window to keep growing beyond any window boundary it's currently touching until it grows into the next closest window boundary ๐Ÿ”ฅ.
  • screen must have an argument which specifies the screen on which to operate.

Here are some examples, bestie ๐Ÿ’–. The following adds a title-bar button to switch a window to the full vertical size of the screen:

Mouse 0 4 A Maximize 0 100

The following causes windows to be stretched to the full width:

Mouse 0 4 A Maximize 100 0

This makes a window that is half the screen size in each direction:

Mouse 0 4 A Maximize 50 50

To expand a window horizontally until any other window is found:

Mouse 0 4 A Maximize 0 grow

To expand a window until any other window on the same or a higher layer is hit:

Mouse 0 4 A Maximize growonlayers $[w.layer] -1 grow grow

To expand a window but leave the lower 60 pixels of the screen unoccupied:

Mouse 0 4 A Maximize 100 -60p

Values bigger than 100? Yeah you can use them, bestie, but with caution ๐Ÿซฃ โ€” that's the vibe, proceed at your own risk.

Refresh

Makes every single window on the screen redraw itself, like a full glow-up for the whole display โœจ. Any pending updates to windows' styles and looks get applied immediately. So if you dropped a Style or TitleStyle command inside a fvwm function and things look stale? This is the "bestie, update your look" button. ๐Ÿ’…

RefreshWindow

Same energy, but for just the one chosen window ๐Ÿ’–. All pending updates of that window's style and look are applied right away โ€” again, perfect when Style or TitleStyle got issued inside a fvwm function and the window is out here still dressed like it's 2019.

Stick [bool]

Sticky windows, but make it a toggle ๐Ÿฉน. If bool is empty or "toggle", this flips the vibe: sticky windows become non-sticky, non-sticky windows become sticky. Want it sticky no matter what its current state is? bool has to be "True". Want it unstuck, periodt? Use "False".

StickAcrossPages [bool]

Works exactly like Stick, but it only sticks a window across pages, not across desks ๐Ÿฆ‹.

StickAcrossDesks [bool]

Works exactly like Stick, but it only sticks a window across desks, not across pages ๐ŸŒธ.

WindowShade [bool] | [[ShadeAgain] direction]

The iconic window shade feature for titled windows ๐Ÿ‘‘. A shaded window only shows off its title-bar, like a little peek-a-boo. Here's the tea:

  • If bool isn't given, or it's "toggle", the shade state flips.
  • bool = "True" forces the window into the shaded state.
  • bool = "False" forces it into the non-shaded state.

Want to force shading in a specific direction? You can pass direction: any of "North", "South", "West", "East", "NorthWest", "NorthEast", "SouthWest", "SouthEast" or "Last". And yes, directions abbreviate with the usual one or two letters โ€” "N", "NW", etc. โœจ

Heads up: using a direction on a window that was already shaded will unshade it. If you want it shaded in a different direction, use the ShadeAgain option.

The direction Last shades the window in whatever direction it was last shaded in. If it's never been shaded before, it shades as if no direction had been given at all. And plot twist โ€” windows without titles can be shaded too ๐Ÿ™ˆ.

Also go check the WindowShadeSteps, WindowShadeShrinks, WindowShadeScrolls, WindowShadeLazy, WindowShadeAlwaysLazy and WindowShadeBusy options of the Style command. Examples, because examples slay:

Style * WindowShadeShrinks, WindowShadeSteps 20, \
  WindowShadeLazy
Mouse 1 - S WindowShade North
Mouse 1 [ S WindowShade West
Mouse 1 ] S WindowShade E
Mouse 1 _ S WindowShade S
Note: when a window that was shaded with a direction argument changes the direction of its window title (see the TitleAtTop Style option), the shading direction does not change. Which may look very strange. ๐Ÿ˜ญ Windows that were shaded without a direction argument stay shaded in the direction of the title bar.

For backward compatibility, the optional argument can also be 1 to mean "on", and 2 to mean "off". But ngl, that syntax is obsolete and will be removed in the future โ€” so don't get attached. ๐Ÿ’€


๐Ÿ–ฑ๏ธโŒจ๏ธ Mouse & Key Bindings โŒจ๏ธ๐Ÿ–ฑ๏ธ

IgnoreModifiers [Modifiers]

Tells fvwm which modifiers to just... ignore ๐Ÿ˜Œ when it's matching Mouse or Key bindings. And yes, IgnoreModifiers affects the ClickToFocus style too. This command belongs in your config, fr fr. If you issue it while your fvwm session is already up and running, the results are unpredictable โ€” so no chaotic mid-session energy with this one. It should appear before any applications or modules are started in your config file (e.g. with the Exec command). ๐Ÿซถ

Modifiers has the same syntax as in Mouse or Key bindings, with the addition of 'L' meaning the caps lock key ๐Ÿ” . The default is "L". Modifiers can be omitted, meaning no modifiers are ignored at all. This command comes in so clutch if the num-lock and scroll-lock keys keep interfering with your shortcuts. With XFree86, '2' usually is the num-lock modifier and '5' refers to the scroll-lock key. To turn all these pesky modifiers off you can use this command:

IgnoreModifiers L25

If the Modifiers argument is the string "default", fvwm reverts back to the default value "L". ๐ŸŒˆ

Important โ€” this command creates a lot of extra network traffic, depending on your CPU, your network connection, the number of Key or Mouse commands in your configuration file, and the number of modifiers you want to ignore. If you do not have a lightning fast machine, or you have very few bindings, you should not ignore more than two modifiers. I.e. do not ignore

if you have no problem with it. In the FAQ you can find a better solution to this problem.

EdgeCommand [screen RANDRNAME] [direction [Function]]

Binds a specified fvwm command Function to an edge of the screen ๐Ÿ–ฅ๏ธโœจ. direction may be one of "North", "Top", "West", "Left", "South", "Bottom", "Right" and "East". If Function is omitted, the binding for this edge is removed. If EdgeCommand is called without any arguments at all, all edge bindings are removed ๐Ÿงน. If the literal option screen followed by a RandR screen name RANDRNAME is given, the command is set only for the given monitor.

Function gets executed when the mouse pointer enters the invisible pan frames that surround the visible screen ๐Ÿ‘€. The binding only works if EdgeThickness is set to a value greater than 0. And here's the trade-off: if a function is bound to an edge, scrolling specified by EdgeScroll is disabled for that edge. It's possible to bind a function to only some edges and use the other edges for scrolling โ€” balance, bestie โš–๏ธ. This command is intended to raise or lower certain windows when the mouse pointer enters an edge. FvwmAuto can be used to get a delay when raising or lowering windows. The following example raises FvwmButtons if the mouse pointer enters the top edge of the screen:

# Disable EdgeScrolling but make it possible
# to move windows over the screen edge
EdgeResistance -1
Style * EdgeMoveDelay 250
Style * EdgeMoveResistance 20

# Set thickness of the edge of the screen to 1
EdgeThickness 1

# Give focus to FvwmButtons if the mouse
# hits top edge
EdgeCommand Top Next (FvwmButtons) Focus
# Make sure the Next command matches the window
Style FvwmButtons CirculateHit

Module FvwmButtons
Module FvwmAuto 100 "Silent AutoRaiseFunction" \
 "Silent AutoLowerFunction"

# If any window except FvwmButtons has
# focus when calling this function
# FvwmButtons are lowered
DestroyFunc AutoLowerFunction
AddToFunc AutoLowerFunction
+ I Current (!FvwmButtons) All (FvwmButtons) Lower

# If FvwmButtons has focus when calling this function raise it
DestroyFunc AutoRaiseFunction
AddToFunc AutoRaiseFunction
+ I Current (FvwmButtons) Raise

Normally, the invisible pan frames are only on the screen edges that border virtual pages ๐Ÿ—บ๏ธ. But if a screen edge has a command bound to it, the pan frame is always created on that edge. Periodt.

EdgeLeaveCommand [screen RANDRNAME] [direction [Function]]

Binds a specified fvwm command Function to an edge of the screen ๐Ÿ–ฅ๏ธ๐Ÿ’œ. direction may be one of "North", "Top", "West", "Left", "South", "Bottom", "Right" and "East". If Function is omitted, the binding for this edge is removed. If EdgeLeaveCommand is called without any arguments, all edge bindings are removed ๐Ÿงน. If the literal option screen followed by a RandR screen name RANDRNAME is given, the command is set only for the given monitor.

Function is executed when the mouse pointer leaves the invisible pan frames that surround the visible screen ๐Ÿ‘‹. The binding works only if EdgeThickness is set to a value greater than 0. If a function is bound to an edge, scrolling specified by EdgeScroll is disabled for this edge. It is possible to bind a function only to some edges and use the other edges for scrolling. This command is intended to raise or lower certain windows when the mouse pointer leaves an edge. FvwmAuto can be used to get a delay when raising or lowering windows. See example for EdgeCommand ๐Ÿ‘†.

Normally, the invisible pan frames are only on the screen edges that border virtual pages. If a screen edge has a command bound to it, the pan frame is always created on that edge. ๐Ÿ’ซ

Key [(window)] Keyname Context Modifiers Function

Binds a keyboard key to a specified fvwm command โŒจ๏ธ๐Ÿ”ฅ โ€” or removes the binding if Function is '-'. The syntax is the same as for a Mouse binding, except the mouse button number gets replaced with a Keyname. Normally, the key binding activates when the key is pressed.

Keyname is a standard X11 key name as defined in /usr/include/X11/keysymdef.h, (without the XK_ prefix), or the keysym database /usr/X11R6/lib/X11/XKeysymDB. Only key names that are generated with no modifier keys or with just the key held are guaranteed to work. The Context and Modifiers fields are defined as in the Mouse binding. However, when you press a key, the context window is the window that has the keyboard focus โ€” which is not necessarily the same as the window the pointer is over (with SloppyFocus or ClickToFocus) ๐Ÿ™ƒ. Also note that key bindings with the 'R' (root window) context do not work properly with SloppyFocus and ClickToFocus. If you run into problems, use the PointerKey command instead. And if you want to bind keys to a window with SloppyFocus or ClickToFocus that are supposed to work when the pointer is not over the window, fvwm assumes the pointer is over the client window โ€” i.e. you have to use the 'W' context.

The special context 'M' for menus can be used to (re)define the menu controls ๐Ÿ”. It can be used alone or together with 'T', 'S', 'I', '[', ']', '-' and '_'. See the Menu Bindings section for details.

The following example binds the built-in window list to pop up when the key is hit, no matter where the mouse pointer is:

Key F11 A SCM WindowList

Binding a key to a title-bar button causes that button to appear ๐Ÿ‘‘. Please refer to the Mouse command for details.

๐Ÿ–ฑ๏ธ Mouse [(window)] Button Context Modifiers Function

Okay so this one makes a mouse binding, and if Function is - it deletes the binding. Simple as that. ๐Ÿ’…

Button is the mouse button number. And here's a lil twist: if Button is zero, then any button does the thing you asked for. But listen โ€” only mouse buttons 1 to 5 are fully supported by X11. Anything above that works only partially. Complex functions can not be used with these buttons, and neither can any operation that requires dragging the pointer with the button held. This is due to limitations of X11, not because fvwm is being dramatic. By default, the highest allowed button number is 9.

Context is where the binding applies, and there are a lot of options, so buckle up bestie:

  • R โ€” the root window
  • W โ€” an application window
  • D โ€” a desktop application (as kdesktop or Nautilus desktop)
  • T โ€” a window title-bar
  • S โ€” a window side, top, or bottom bar
  • [, ], - and _ โ€” the left, right, top or bottom side only
  • F โ€” a window frame (the corners)
  • <, ^, > and v โ€” the top left, top right, bottom right or bottom left corner
  • I โ€” an icon window
  • 0 through 9 โ€” title-bar buttons
  • any combination of these letters ๐Ÿ’ซ
  • A โ€” any context

For instance, a context of "FST" applies when the mouse is anywhere in a window's border except the title-bar buttons. And heads up: only S and W are valid for an undecorated window.

The special context M for menus can be used to (re)define the menu controls. It can be used alone or together with T, S, I, [, ], - and _. See the Menu Bindings section for details. ๐Ÿ‘€

The special context P controls what buttons that can be used to place a window. When you're using this context: no modifiers are allowed (Modifiers must be N), no window is allowed, and the Function must be one of PlaceWindow, PlaceWindowDrag, PlaceWindowInteractive, CancelPlacement, CancelPlacementDrag, CancelPlacementInteractive or -.

So what do those do? PlaceWindow makes Button usable for window placement, both for interactive and drag move. CancelPlacement does the inverse โ€” it makes Button cancel move for both interactive and drag move. It may however not override how new windows are resized after being placed. That's controlled by the Emulate command. Also, a window being dragged can always be placed by releasing the button hold while dragging, regardless of if it is set to PlaceWindow or not.

PlaceWindowDrag and PlaceWindowInteractive / CancelPlacementDrag and CancelPlacementInteractive work as PlaceWindow / CancelPlacement with the exception that they only affect either windows dragged / placed interactively.

And - is equivalent to CancelPlacement.

The following example makes all buttons but button 3 usable for interactive placement, and makes drag moves started by other buttons than one cancel if button 1 is pressed before finishing the move:

Mouse 0 P N PlaceWindow
Mouse 3 P N CancelPlacement
Mouse 1 P N CancelPlacementDrag

By default, the binding applies to all windows. You can specify that a binding only applies to specific windows by specifying the window name in brackets. The window name is a wildcard pattern specifying the class, resource or name of the window you want the binding to apply to. ๐ŸŽฏ

The following example shows how the same key-binding can be used to perform different functions depending on the window that is focused:

Key (rxvt)  V A C Echo ctrl-V-in-RXVT
Key (*term) V A C Echo ctrl-V-in-Term
Key (*vim)  V A C --
Key         V A C Echo ctrl-V-elsewhere

A -- action indicates that the event should be propagated to the specified window to handle. This is only a valid action for window-specific bindings.

This example shows how to display the WindowList when Button 3 is pressed on an rxvt window:

Mouse (rxvt) 3 A A WindowList
Note that Fvwm actually intercepts all events for a window-specific binding and (if the focused window doesn't match any of the bindings) sends a synthetic copy of the event to the window. This should be transparent to most applications, however (for security reasons) some programs ignore these synthetic events by default โ€” xterm is one of them. To enable handling of these events, add the following line to your ~/.Xdefaults file:
XTerm*allowSendEvents:  true

Modifiers is any combination of N for no modifiers, C for control, S for shift, M for Meta, L for Caps-Lock or A for any modifier. For example, a modifier of "SM" applies when both the and keys are down. (Yeah the manpage literally leaves those two key names blank right there ๐Ÿ’€ iconic behaviour, we move on.)

X11 modifiers mod1 through mod5 are represented as the digits 1 through 5. The modifier L is ignored by default. To turn it on, use the IgnoreModifiers command.

Function is one of fvwm's commands.

The title-bar buttons are numbered with odd numbered buttons on the left side of the title-bar and even numbers on the right. Smaller-numbered buttons are displayed toward the outside of the window while larger-numbered buttons appear toward the middle of the window (0 is short for 10). In summary, the buttons are numbered:

1 3 5 7 9    0 8 6 4 2

The highest odd numbered button which has an action bound to it determines the number of buttons drawn on the left side of the title bar. The highest even number determines the number of right side buttons which are drawn. Actions can be bound to either mouse buttons or keyboard keys. ๐ŸŽ€


โœจ PointerKey [(window)] Keyname Context Modifiers Function

This command works exactly like the Key command. The only difference is that the binding operates on the window under the pointer. Normal key bindings operate on the focused window instead. The PointerKey command can for example be used to bind keys to the root window if you are using SloppyFocus or ClickToFocus.

However โ€” and this is the part where you go ๐Ÿ™ˆ โ€” some applications (xterm is one example) are unable to handle this key anymore, even if the pointer is over the xterm window. So it is recommended to use the PointerKey command only for key combinations that are not needed in any application window.

Example:

Style * SloppyFocus
PointerKey f1 a m Menu MainMenu

๐Ÿ‘‘ Controlling Window Styles ๐Ÿ‘‘

For readability, the commands in this section are not sorted alphabetically. The description of the Style command can be found at the end of this section.

The commands: FocusStyle, Style, and WindowStyle can accept optional conditional components to match some properties of a window.

For example:

Style (Name mc) Sticky

Will make a window whose name matched 'mc' Sticky.

Style (Name mc, Class XTerm) StartIconic

This example will start an xterm(1) window whose WM_CLASS matches 'XTerm' and name is 'mc'.

A valid list of properties to test against are:

  • Resource
  • Class
  • Name
  • Icon
  • WindowID

The matching of the properties specified for any Style line are ANDed together, and for styles to be applied, all properties must match.

NOTE: To destroy a style line with window properties, DestroyStyle should be used. For example:
DestroyStyle (Name mc, Class XTerm)

It is not required to specify the style arguments when destroying a style, only the property components are required.

Existing Style lines in the form:

Style Application* Sticky, StartIconic

are still supported, and their behaviour remains unchanged.


๐Ÿ’– FocusStyle stylename options

works exactly like the Style command, but accepts only the focus policy related styles beginning with "FP". The prefix can be removed, but at the cost of a little bit of time. FocusStyle is meant to make the configuration file more readable. Example:

FocusStyle * EnterToFocus, !LeaveToUnfocus

is equivalent to

Style * FPEnterToFocus, !FPLeaveToUnfocus

๐Ÿ’€ DestroyStyle style

deletes the style named style. The changes take effect immediately. Note that style is not a wild-carded search string, but rather a case-sensitive string that should exactly match the original Style command.

Destroying style "*" can be done, but isn't really to be recommended. For example:

DestroyStyle Application*

This removes all settings for the style named "Application*", NOT all styles starting with "Application".

๐Ÿงน DestroyWindowStyle

deletes the styles set by the WindowStyle command on the selected window. The changes take effect immediately.

โšก UpdateStyles

All pending updates of all windows' styles and looks are applied immediately. E.g. if Style, WindowStyle or TitleStyle commands were issued inside a fvwm function.

๐ŸŒธ Style stylename options ...

The Style command is used to set attributes of a window to values other than the default or to set the window manager default styles.

stylename can be a window's name, class, visible name, or resource string. It may contain the wildcards '*' and '?', which are matched in the usual Unix filename manner. Multiple style options in a single Style command are read from left to right as if they were issued one after each other in separate commands. A given style always overrides all conflicting styles that have been issued earlier (or further left on the same style line).

Note: windows that have no name (WM_NAME) are given a name of "Untitled", and windows that do not have a class (WM_CLASS, res_class) are given class "NoClass" and those that do not have a resource (WM_CLASS, res_name) are given resource "NoResource".

If a window has the resource "fvwmstyle" set, the value of that resource is used in addition to any window names when selecting the style. ๐Ÿฆ‹

Okay so options? It's a comma separated list with one or more of the keywords below, bestie. And here's the lil rule you gotta internalise: each group of style names is separated by slashes (/), and the last style in these groups is the default. So when you see a slash sandwich, read right-to-left for the vibe check on what fvwm does when you say nothing at all. ๐Ÿ’…

Here's the whole menu, every single one, no skips:

BorderWidth, HandleWidth, CornerLength, !Icon / Icon, MiniIcon,
IconBox, IconGrid, IconFill, IconSize, !Title / Title, TitleAtBottom
/ TitleAtLeft / TitleAtRight / TitleAtTop, LeftTitleRotatedCW /
LeftTitleRotatedCCW, RightTitleRotatedCCW / RightTitleRotatedCW,
TopTitleRotated / TopTitleNotRotated, BottomTitleRotated /
BottomTitleNotRotated, !UseTitleDecorRotation /
UseTitleDecorRotation, StippledTitle / !StippledTitle,
StippledIconTitle / !StippledIconTitle, IndexedWindowName /
ExactWindowName, IndexedIconName / ExactIconName, TitleFormat /
IconTitleFormat / !Borders / Borders, !Handles / Handles,
WindowListSkip / WindowListHit, CirculateSkip / CirculateHit,
CirculateSkipShaded / CirculateHitShaded, CirculateSkipIcon /
CirculateHitIcon, Layer, StaysOnTop / StaysOnBottom / StaysPut,
Sticky / Slippery, StickyAcrossPages / !StickyAcrossPages,
StickyAcrossDesks / !StickyAcrossDesks, !StickyStippledTitle /
StickyStippledTitle, !StickyStippledIconTitle /
StickyStippledIconTitle, StartIconic / StartNormal,  Colorset,
HilightColorset, BorderColorset, HilightBorderColorset,
IconTitleColorset, HilightIconTitleColorset, IconBackgroundColorset,
IconTitleRelief, IconBackgroundRelief, IconBackgroundPadding, Font,
IconFont, StartsOnDesk / StartsOnPage / StartsAnyWhere,
StartsOnScreen, StartShaded / !StartShaded,
ManualPlacementHonorsStartsOnPage /
ManualPlacementIgnoresStartsOnPage, CaptureHonorsStartsOnPage /
CaptureIgnoresStartsOnPage, RecaptureHonorsStartsOnPage /
RecaptureIgnoresStartsOnPage, StartsOnPageIncludesTransients /
StartsOnPageIgnoresTransients, IconTitle / !IconTitle, MwmButtons /
FvwmButtons, MwmBorder / FvwmBorder, MwmDecor / !MwmDecor,
MwmFunctions / !MwmFunctions, HintOverride / !HintOverride, !Button
/ Button, ResizeHintOverride / !ResizeHintOverride, OLDecor /
!OLDecor, StickyIcon / SlipperyIcon, StickyAcrossPagesIcon /
!StickyAcrossPagesIcon, StickyAcrossDesksIcon /
!StickyAcrossDesksIcon, ManualPlacement / CascadePlacement /
MinOverlapPlacement / MinOverlapPercentPlacement /
TileManualPlacement / TileCascadePlacement / PositionPlacement,
MinOverlapPlacementPenalties, MinOverlapPercentPlacementPenalties,
DecorateTransient / NakedTransient, DontRaiseTransient /
RaiseTransient, DontLowerTransient / LowerTransient,
DontStackTransientParent / StackTransientParent, SkipMapping /
ShowMapping, ScatterWindowGroups / KeepWindowGroupsOnDesk, UseDecor,
UseStyle, !UsePPosition / NoPPosition / UsePPosition,
!UseUSPosition, NoUSPosition / UseUSPosition,
!UseTransientPPosition, NoTransientPPosition /
UseTransientPPosition, !UseTransientUSPosition /
NoTransientUSPosition / UseTransientUSPosition, !UseIconPosition /
NoIconPosition / UseIconPosition, Lenience / !Lenience, ClickToFocus
/ SloppyFocus / MouseFocus|FocusFollowsMouse / NeverFocus,
ClickToFocusPassesClickOff / ClickToFocusPassesClick,
ClickToFocusRaisesOff / ClickToFocusRaises, MouseFocusClickRaises /
MouseFocusClickRaisesOff, GrabFocus / GrabFocusOff,
GrabFocusTransientOff / GrabFocusTransient, FPFocusClickButtons,
FPFocusClickModifiers, !FPSortWindowlistByFocus /
FPSortWindowlistByFocus, FPClickRaisesFocused /
!FPClickRaisesFocused, FPClickDecorRaisesFocused /
!FPClickDecorRaisesFocused, FPClickIconRaisesFocused /
!FPClickIconRaisesFocused, !FPClickRaisesUnfocused /
FPClickRaisesUnfocused, FPClickDecorRaisesUnfocused /
!FPClickDecorRaisesUnfocused, FPClickIconRaisesUnfocused /
!FPClickIconRaisesUnfocused, FPClickToFocus / !FPClickToFocus,
FPClickDecorToFocus / !FPClickDecorToFocus, FPClickIconToFocus /
!FPClickIconToFocus, !FPEnterToFocus / FPEnterToFocus,
!FPLeaveToUnfocus / FPLeaveToUnfocus, !FPFocusByProgram /
FPFocusByProgram, !FPFocusByFunction / FPFocusByFunction,
FPFocusByFunctionWarpPointer / !FPFocusByFunctionWarpPointer,
FPLenient / !FPLenient, !FPPassFocusClick / FPPassFocusClick,
!FPPassRaiseClick / FPPassRaiseClick, FPIgnoreFocusClickMotion /
!FPIgnoreFocusClickMotion, FPIgnoreRaiseClickMotion /
!FPIgnoreRaiseClickMotion, !FPAllowFocusClickFunction /
FPAllowFocusClickFunction, !FPAllowRaiseClickFunction /
FPAllowRaiseClickFunction, FPGrabFocus / !FPGrabFocus,
!FPGrabFocusTransient / FPGrabFocusTransient, FPOverrideGrabFocus /
!FPOverrideGrabFocus, FPReleaseFocus / !FPReleaseFocus,
!FPReleaseFocusTransient / FPReleaseFocusTransient,
FPOverrideReleaseFocus / !FPOverrideReleaseFocus, StartsLowered /
StartsRaised, IgnoreRestack / AllowRestack, FixedPosition /
VariablePosition, FixedUSPosition / VariableUSPosition,
FixedPPosition / VariablePPosition, FixedSize / VariableSize,
FixedUSSize / VariableUSSize, FixedPSize / VariablePSize, !Closable
/ Closable, !Iconifiable / Iconifiable, !Maximizable / Maximizable,
!AllowMaximizeFixedSize / AllowMaximizeFixedSize, IconOverride /
NoIconOverride / NoActiveIconOverride, DepressableBorder /
FirmBorder, MinWindowSize, MaxWindowSize, IconifyWindowGroups /
IconifyWindowGroupsOff, ResizeOpaque / ResizeOutline, BackingStore /
BackingStoreOff / BackingStoreWindowDefault, Opacity /
ParentalRelativity, SaveUnder / SaveUnderOff, WindowShadeShrinks /
WindowShadeScrolls, WindowShadeSteps, WindowShadeAlwaysLazy /
WindowShadeBusy / WindowShadeLazy, EWMHDonateIcon /
EWMHDontDonateIcon, EWMHDonateMiniIcon / EWMHDontDonateMiniIcon,
EWMHMiniIconOverride / EWMHNoMiniIconOverride,
EWMHUseStackingOrderHints / EWMHIgnoreStackingOrderHints,
EWMHIgnoreStateHints / EWMHUseStateHints, EWMHIgnoreStrutHints /
EWMHUseStrutHints, EWMHIgnoreWindowType / !EWMHIgnoreWindowType,
EWMHMaximizeIgnoreWorkingArea / EWMHMaximizeUseWorkingArea /
EWMHMaximizeUseDynamicWorkingArea, EWMHPlacementIgnoreWorkingArea /
EWMHPlacementUseWorkingArea / EWMHPlacementUseDynamicWorkingArea,
MoveByProgramMethod, Unmanaged, State, SnapGrid, SnapAttraction,
EdgeMoveDelay, EdgeResizeDelay. EdgeMoveResistance,
InitialMapCommand

Yeah I know, it's giving phone book. ๐Ÿ“– It's the whole thing though, no crumbs left out.


Also, a lil heads-up on the format: some of the options above show up as style-option/opposite-style-option. And the opposite-style-option, for the entries that actually have one, is what describes the fvwm default behaviour โ€” so you reach for it when you wanna flip the default. Like, that's literally its whole job. ๐Ÿซถ


Focus policy ๐ŸŽฏ

  • ClickToFocus โ€” tells fvwm to hand over the focus when you click inside a window. Classic.
  • MouseFocus โ€” and this is the default, bestie, so this is the energy you get for free. It's also known as its alias FocusFollowsMouse. The pointer enters a window โ†’ it gets the focus. Pointer leaves โ†’ the focus is taken away. That simple.
  • SloppyFocus โ€” basically the same vibe, but with boundaries: it does not give up focus if the pointer leaves the window to pass over the root window or over a ClickToFocus window (unless you click on it, obviously). So you can yeet your mouse out of the way without losing your spot. Iconic behaviour, honestly.
  • NeverFocus โ€” a window with this style never receives the focus, periodt. Super useful for modules like FvwmButtons, for example.
Note: once you've used any of the FP... styles, the defaults that come bundled with the basic focus policies are not restored when you go back to using those. So like, once !FPGrabFocus has been used, using ClickToFocus does not restore FPGrabFocus. It's gone, girl. ๐Ÿ’€

The focus model can be augmented with several additional options. In fvwm-2.5.3 and later there's a whole crowd of advanced options that start with FP or !FP. These are destined to replace the older options one day, and they're described first. Heads up though: using any of these new options may limit compatibility with older releases. In general, options beginning with FP turn a feature on, while those beginning with !FP turn it off. โœจ

Focusing the window ๐Ÿ”

  • FPEnterToFocus โ€” when the pointer enters a window, it receives focus.
  • FPLeaveToUnfocus โ€” a window loses focus when the pointer leaves it.
  • FPClickToFocus, FPClickDecorToFocus or FPClickIconToFocus โ€” a window receives focus when the inside of the window, or its decorations, or its icon is clicked. Pick your fave target. ๐ŸŽ€
  • FPFocusByProgram โ€” allows windows to take the focus themselves. Main character energy, lowkey.
  • !FPFocusByFunction โ€” forbids a window from receiving focus via the Focus and FlipFocus commands.
  • FPFocusByFunctionWarpPointer โ€” controls whether the pointer is warped over to a selected window when the Focus command is used.
  • FPLenient โ€” allows focus on windows that don't even want it, like FvwmPager or xclock. They're shy, but we love them.
  • FPFocusClickButtons โ€” takes a list of mouse buttons that can be clicked to focus or raise a window when the appropriate style is used. The default is to use the first three buttons ("123").
  • FPFocusClickModifiers โ€” takes a list of modifier keys, just like the Key command. The exact combination of modifier keys must be pressed for the click to focus or raise a window to work. The default is to use no modifiers ("N").
  • FPPassFocusClick โ€” the click that was used to focus a window gets passed along to the application. Sharing is caring. ๐Ÿซถ
  • FPAllowFocusClickFunction โ€” the click that was used to focus a window can also trigger a normal action that was bound to that window with the Mouse command.
  • FPIgnoreFocusClickMotion โ€” if you use this, clicking in a window and then dragging the pointer with the button held down does not count as a click-to-focus. Instead the application processes those events normally. Which is genuinely so useful for selecting text in a terminal window with the mouse without raising the window. But: mouse bindings on the client window are not guaranteed to work anymore (see the Mouse command). This style forces the initial click to be passed to the application. The distance the pointer has to move to trigger this is controlled by the MoveThreshold command.
  • FPSortWindowlistByFocus and !FPSortWindowlistByFocus โ€” these control whether the internal window list is sorted in the order the windows were focused, or in the order they were created. The latter is the default for ClickToFocus and SloppyFocus. ๐Ÿฆ‹

And that's the focus tea for now โ€” the list keeps going, so don't wander off, bestie. ๐ŸŒธ

โœจ Clicking the window to raise โœจ

okay so bestie, there are three matching trios here and they're all about the moment of the click ๐Ÿ’…

  • FPClickRaisesFocused, FPClickDecorRaisesFocused, FPClickIconRaisesFocused โ€” these let you raise the window when the interior, the decorations, or the icon of the window gets clicked, but only while the window is already focused.
  • FPClickRaisesUnfocused, FPClickDecorRaisesUnfocused, FPClickIconRaisesUnfocused โ€” same energy, different timing: these raise the window when the interior, decorations, or icon is clicked while the window is not yet focused โœจ
  • FPPassRaiseClick โ€” with this style, the very click that raised the window gets passed on to the application. sharing is caring ๐Ÿซถ
  • FPAllowRaiseClickFunction โ€” with this one, the click that raised the window can also trigger a normal action that was bound to the window with the Mouse command.
  • FPIgnoreRaiseClickMotion โ€” if this style is on, clicking in a window and then dragging the pointer with the button held down does not count as the click to raise the window. Instead, the application processes these events normally. This is lowkey iconic for selecting text in a terminal window with the mouse without raising the window. However, mouse bindings on the client window are not guaranteed to work anymore (see Mouse command). Note that this style forces the initial click to be passed to the application. The distance the pointer must be moved to trigger this is controlled by the MoveThreshold command.

๐ŸŒˆ Grabbing the focus when a new window is created ๐ŸŒˆ

New normal or transient windows with the FPGrabFocus or FPGrabFocusTransient style automatically receive the focus when they're created. FPGrabFocus is the default for windows with the ClickToFocus style. Note: even if these styles are disabled, the application may take the focus itself โ€” fvwm literally cannot prevent this, no cap ๐Ÿ˜ญ

  • OverrideGrabFocus โ€” this one tells fvwm to never take away the focus from such a window via the GrabFocus or GrabFocusTransient styles. Super useful if you love transient windows grabbing focus immediately (think: a web browser) but you do not want that happening while you're vibing in a terminal window or a text processor ๐Ÿ‘‘

The above three styles are accompanied by FPReleaseFocus, FPReleaseFocusTransient and FPOverrideReleaseFocus. These control whether the focus is returned to another window when the window is closed. Otherwise, no window โ€” or the window under the pointer โ€” receives the focus.

  • ClickToFocusPassesClickOff and ClickToFocusPassesClick โ€” these control whether a mouse click used to focus a window is sent to the application or not.
  • ClickToFocusRaisesOff / MouseFocusClickRaisesOff and ClickToFocusRaises / MouseFocusClickRaises โ€” these control whether the window is raised (but this depends on the focus model, bestie).
Note: in fvwm versions prior to 2.5.3, the "Click..." options applied only to windows with ClickToFocus while the "Mouse..." options applied to windows with a different focus policy. This is no longer the case.
  • The old GrabFocus style is equivalent to using FPGrabFocus FPReleaseFocus.
  • The old GrabFocusTransient style is equivalent to using FPGrabFocusTransient + FPReleaseFocusTransient.
  • Lenience is equivalent to the new style FPLenient.

๐ŸŽ€ Window title ๐ŸŽ€

The Title and !Title options determine whether the window is decorated with a title-bar. By default, all windows have a title-bar. NoTitle is equivalent to !Title but it's deprecated (rip ๐Ÿชฆ).

Windows with the TitleAtBottom, TitleAtLeft or TitleAtRight style have a title-bar below, to the left or to the right of the window instead of above like usual. The TitleAtTop style restores the default placement. And here's the thing โ€” even if the window has the !Title style set, this still affects the WindowShade command. Please go check the WindowShade command for the interactions between that command and these styles, iykyk. Titles on the left or right side of the windows are augmented by the following styles:

Normally, the text in titles on the left side of a window is rotated counterclockwise by 90 degrees from the normal upright position, and 90 degrees clockwise for titles on the right side. It can also be rotated in the opposite directions with LeftTitleRotatedCW if TitleAtLeft is used, and with RightTitleRotatedCCW if TitleAtRight is used. The defaults can be restored with LeftTitleRotatedCCW and RightTitleRotatedCW. A normal horizontal text may be rotated as well with TopTitleRotated if TitleAtTop is used, and with BottomTitleRotated if TitleAtBottom is used. The defaults can be restored with TopTitleNotRotated and BottomTitleNotRotated ๐Ÿ’ซ

By default, the title bar decoration defined using the TitleStyle command is rotated following the title text rotation (see the previous paragraph, bestie, keep up ๐Ÿ’–). This can be disabled by using the !UseTitleDecorRotation style. UseTitleDecorRotation reverts back to the default.

  • StippledTitle โ€” titles get drawn with the same effect that's usually reserved for windows with the Sticky, StickyAcrossPages or StickyAcrossDesks style. !StippledTitle reverts back to normal titles. StippledTitleOff is equivalent to !StippledTitle but is deprecated.
  • Colorset โ€” takes the colorset number as its sole argument and overrides the colors set by Color. Instead, the corresponding colors from the given colorset get used. Note that all other features of a colorset are not used. Use the Colorset decoration style in the TitleStyle and ButtonStyle command for that. To stop using the colorset, just omit the colorset number.
  • BorderColorset โ€” takes eight positive integers as its arguments and applies the given colorsets to the eight individual components of the window border. For backwards compatibility, if one integer is supplied, that one gets applied to all window border components.

The border is split up into the following definitions, and it's in the same order as the colorsets which will be applied to the border:

BorderColorset North, North East, East, South East, South, South West, West, North West

North, East, South, and West refer to the top, left, bottom, and right sides of the window border. NE, SE, SW, and NW refer to the window handles.

NOTE: due to how window handles are rendered, there is no way to make one complete edge of a window the same color as defined by either North, South, East, or West. it's giving โœจlimitationsโœจ
  • HilightBorderColorset โ€” works the same as BorderColorset but it's used when the window has the focus ๐Ÿ”ฅ
  • !IconTitle โ€” disables displaying icon labels, while the opposite style IconTitle enables icon labels (that's the default behaviour). NoIconTitle is equivalent to !IconTitle but is deprecated.
  • IconTitleColorset โ€” takes the colorset number as its sole argument and overrides the colors set by Color or Colorset. To stop using this colorset, the argument is omitted.
  • HilightIconTitleColorset โ€” takes the colorset number as its sole argument and overrides the colors set by HilightColorset. To stop using this colorset, the argument is omitted.
  • IconBackgroundColorset โ€” takes the colorset number as its sole argument and uses it to set a background for the icon picture. By default, the icon picture is not drawn onto a background image. To restore the default, the argument is omitted.
  • IconTitleRelief โ€” takes one numeric argument that may be between -50 and +50 pixels and defines the thickness of the 3D relief drawn around the icon title. With negative values, the icon title gets a pressed-in look. The default is 2 and it's restored if the argument is omitted.
  • IconBackgroundRelief โ€” takes one numeric argument that may be between -50 and +50 pixels and defines the thickness of the 3D relief drawn around the icon picture background (if any). With negative values, the icon background gets a pressed-in look. The default is 2 and it's restored if the argument is omitted.
  • IconBackgroundPadding โ€” takes one numeric argument that may be between 0 and 50 pixels and defines the amount of free space between the relief of the icon background picture (if any) and the icon picture. The default is 2 and it's restored if the argument is omitted.
  • Font and IconFont โ€” take the name of a font as their sole argument. This font is used in the window or icon title. By default, the font given in the DefaultFont command is used. To revert back to the default, use the style without the name argument ๐Ÿ’œ
  • IndexedWindowName (deprecated, bestie, it's old) โ€” causes fvwm to use window titles in the form:
name (i)

where name is the exact window name and i is an integer which represents the i th window with name as window name. This has been replaced with:

TitleFormat %n (%t)

ExactWindowName restores the default, which is to use the exact window name. Deprecated in favour of:

TitleFormat %n

IndexedIconName and ExactIconName work the same as IndexedWindowName and ExactWindowName styles but for the icon titles. Both are deprecated in favour of:

IconTitleFormat %n (%t)
IconTitleFormat %n

TitleFormat describes what the visible name of a window should look like, with the following placeholders being valid:

  • %n โ€” Insert the window's name.
  • %i โ€” Insert the window's icon name.
  • %c โ€” Insert the window's class name.
  • %r โ€” Insert the window's resource name.
  • %t โ€” Insert the window count.
  • %I โ€” Insert the window ID.
  • %% โ€” Insert a literal '%' character.

Any amount of whitespace may be used, along with other characters, to make up the string โ€” but a valid TitleFormat string must contain at least one of the placeholders mentioned. No quote stripping is performed on the string, so for example the following is printed verbatim:

TitleFormat " %n " -> [%t] ->      [%c]
Note: It's perfectly possible to use a TitleFormat which can result in wiping out the visible title altogether ๐Ÿ’€ For example:
TitleFormat %z

Simply because the placeholder '%z' isn't supported. Not a bug, bestie โ€” it's just a little facet of how the formatting parser works. ๐Ÿ’…

IconTitleFormat describes what the visible icon name of a window should look like, and the options are the exact same ones as TitleFormat. Same energy, different target. โœจ

๐ŸŽ€ Title buttons

  • Button, !Button โ€” takes a numeric argument, which is the number of the title-bar button that's gonna be shown or omitted. Slay or yeet, your call. ๐Ÿ’…
  • NoButton โ€” literally equivalent to !Button, but it's deprecated, so maybe don't.
  • MwmButtons โ€” makes the Maximize button look pressed-in when the window is maximized. Peep the MwmDecorMax flag in ButtonStyle for the deets. Want to turn it back off? Use the FvwmButtons style. ๐Ÿฆ‹

๐ŸŒธ Borders

  • !Borders โ€” suppresses the window border (but not the title) completely. The Borders style turns them back on. And heads up: without borders, every other style that messes with window borders is just meaningless. Nothing. Void. ๐Ÿ’€
  • MwmBorder โ€” makes the 3D bevel match Mwm's a lil more closely. FvwmBorder turns that previous option off again.
  • !Handles โ€” with this, the window does not get the handles in the window corners that people commonly use to resize it. With !Handles, the width comes from the BorderWidth style. By default โ€” or if Handles is specified โ€” the width comes from the HandleWidth style instead. NoHandles is equivalent to !Handles but it's deprecated, so like, don't. ๐Ÿ™ˆ
  • HandleWidth โ€” takes a numeric argument: the width of the border to place the window with if it does have resize-handles. Call HandleWidth with no argument and it restores the default. ๐ŸŽ€
  • CornerLength โ€” takes a single numeric argument: the length, in pixels, of the corner handles. Default is the title height. Call it without an argument and boom, default restored. โœจ
  • BorderWidth โ€” takes a numeric argument: the width of the border to place the window with if it does not have resize-handles. Only used if the !Handles style is specified too. No argument = default restored. ๐Ÿ’–
  • DepressableBorder โ€” makes the border parts of the window decoration look all sunken in when a button is pressed over them. You can disable this again with the FirmBorder style. ๐Ÿซถ

๐Ÿฆ‹ Icons, shading, maximizing, movement, resizing

  • Icon โ€” takes an (optional) unquoted string argument: the icon bitmap or pixmap to use. Icons specified this way override pixmap icons, but not icon windows and not the ewmh icon that the client hands over in the application (via the WM_HINTS property or via the ewmh _NET_WM_ICON property).

The IconOverride style flips the behavior so it overrides any client-provided icons. The NoIconOverride style flips it to not override any client-provided icons. And the default overriding behavior can be switched back on with the NoActiveIconOverride style. With that style, fvwm uses the application-provided icons once the icon is changed โ€” but until then, it uses the icon from the configuration file. ๐Ÿ˜Œ

There's one exception to all of these rules, and it's literally this:

Style * Icon unknown.xpm

This does not force unknown.xpm on every single window โ€” it just sets the default icon, same as the DefaultIcon command. But if you really want every window to rock the same icon, you go:

Style ** Icon unknown.xpm

And if the NoIcon attribute is set, the specified window just disappears when it's iconified. You can still rescue it through the window-list, no cap. If Icon is set without an argument, the NoIcon attribute gets cleared but no icon is actually specified. Here's an example that lets only the FvwmPager module icon exist:

Style * NoIcon
Style FvwmPager Icon
  • IconBox โ€” takes no argument, four numeric arguments (plus optionally a screen specification), an X11 geometry string, or the string "none":
IconBox [screen scr-spec] l t r b

or

IconBox geometry

Where l is the left coordinate, t is the top, r is right, and b is bottom. Negative coordinates mean distance from the right or bottom of the screen. If the first argument is the word screen, then the scr-spec argument specifies the RandR screen on which the IconBox is defined โ€” or the extra 'w' for the screen where the window center is located. This is only useful with multiple screens, jsyk. The "l t r b" spec is more flexible than an X11 geometry. For example:

IconBox -80 240 -1 -1

defines a box that's 80 pixels wide from the right edge, 240 pixels down from the top, and keeps going to the bottom of the screen. ๐ŸŽ€

Tho honestly it might be easier to use an X11 geometry string:

IconBox 1000x70-1-1

places a 1000 by 70 pixel icon box on the bottom of the screen, starting in the lower right hand corner. One way to figure out a geometry like this is to use a window that resizes in pixel increments โ€” like, say, xv. Resize and place the xv window exactly where you want the iconbox, then use FvwmIdent to read the window's geometry. Iconic. ๐Ÿ‘‘

So the icon box is a region of the screen where fvwm tries to put icons for any matching window, as long as they don't overlap other icons. You can define multiple icon boxes as overflow areas โ€” when the first icon box is full, the second one starts filling up. All the icon boxes for one style must be defined in one single Style command. Like:

Style * IconBox -80 240 -1 -1, \
  IconBox 1000x70-1-1

A Style command with the IconBox option replaces any icon box defined previously by another Style command for the same style. That's literally why the backslash in the previous example is required. ๐Ÿซ 

Note: the geometry for the icon box command takes the additional screen specifier "@w" in case RandR is used. This designates the screen where the window center is located. This extra screen specifier is not allowed anywhere else. Periodt.

If you never define an icon box, or you fill all the icon boxes, fvwm has a default icon box that covers the screen โ€” it fills top to bottom, then left to right, and it's got an 80x80 pixel grid. To disable all but the default icon box, you can use IconBox without arguments in a separate Style command. And to disable all icon boxes, including the default one, you can pass the argument "none". ๐Ÿ’…

Hint: you can auto arrange your icons in the icon box with a simple fvwm function. Drop this "DeiconifyAndRearrange" function into your configuration file:
AddToFunc DeiconifyAndRearrange
 + C Iconify off
 + C All (CurrentPage, Iconic) PlaceAgain Icon

Then replace every place where you call the Iconify command to de-iconify an icon with a call to the new function. For example, replace

AddToFunc IconFunc
 + C Iconify off
 + M Raise
 + M Move
 + D Iconify off

Mouse 1 I A Iconify off

with

AddToFunc IconFunc
 + C DeiconifyAndRearrange
 + M Raise
 + M Move
 + D DeiconifyAndRearrange

Mouse 1 I A DeiconifyAndRearrange
  • IconGrid โ€” takes 2 numeric arguments greater than zero.
IconGrid x y

Icons get placed in an icon box by stepping through the icon box using the x and y values for the icon grid, hunting for a free space. The default grid is 3 by 3 pixels, which gives that tightly packed look. Want something more regular? Use a grid bigger than your largest icon. And use the IconSize argument to clip or stretch an icon to a maximum size. An IconGrid definition must follow the IconBox definition it applies to:

Style * IconBox -80x240-1-1, IconGrid 90 90
  • IconFill โ€” takes 2 arguments.
IconFill Bottom Right

Icons get placed in an icon box by stepping through it, using these arguments to control the direction the box fills in. By default the direction is left to right, then top to bottom. Which would be expressed as:

IconFill left top

To fill an icon box in columns instead of rows, specify the vertical direction (top or bottom) first. The directions can be abbreviated or spelled all the way out: "t", "top", "b", "bot", "bottom", "l", "lft", "left", "r", "rgt", "right". An IconFill definition must follow the IconBox definition it applies to:

Style * IconBox -80x240-1-1, IconFill b r
  • IconSize โ€” sets limits on the size of an icon image. Both user-provided and application-provided icon images are affected. ๐Ÿ’–
IconSize [ width height [ maxwidth maxheight ] ]

All arguments are measured in pixels. When all four arguments get passed to IconSize, width and height represent the minimum size of an icon, and maxwidth and maxheight represent the maximum size of an icon. Icon images smaller than the minimum size get padded. Icon images bigger than the maximum size get clipped. โœ‚๏ธ

If only two arguments get passed to IconSize, width and height represent the absolute size of an icon. Icons covered by this style are padded or clipped to hit that given size.

If no arguments are specified, the default values are used for each dimension โ€” which effectively places no limits on the size of an icon.

The value "-1" can be used in place of any of the arguments to specify the default value for that dimension.

On top of the numeric arguments, 1 additional argument can be "Stretched", "Adjusted", or "Shrunk".

Note: module provided icon managers are not affected by this style. ๐Ÿ™…โ€โ™€๏ธ
  • MiniIcon โ€” specifies a pixmap to use as the miniature icon for the window. This mini icon can be drawn in a title-bar button (see ButtonStyle), and it can be used by various fvwm modules (FvwmIconMan and FvwmPager). It takes the name of a pixmap as an argument. ๐ŸŽ€
  • WindowShadeShrinks, WindowShadeScrolls โ€” control whether the contents of a window being shaded with the WindowShade command are scrolled (that's the default) or whether they stay in place. The shrinking mode is a lil bit faster. โœจ
  • WindowShadeSteps โ€” selects the number of steps for the animation when shading a window with WindowShade. It takes one number as its argument. If that number has a trailing 'p', it sets the number of pixels to use as the step size instead of a fixed number of steps. 0 disables the animation. Which also happens if the argument is omitted or invalid. ๐Ÿ’€

Okay so the WindowShade command has two modes of operation, bestie: busy shading and lazy shading. Busy shading can be 50% slower than lazy shading, but the latter can look strange under some conditions โ€” like, for example, if the window borders, buttons or the title are filled with a tiled pixmap. ๐Ÿ’€ Also, the window handles are not drawn in lazy mode, and the border relief may only be drawn partially right before the window reaches the shaded state, or right after it leaves the unshaded state. It's giving mid-transition chaos.

By default, fvwm uses lazy mode if there are no bad visual effects (and no, the window handles don't count), and busy mode otherwise. Wanna force it? Use WindowShadeAlwaysLazy or WindowShadeBusy to force using the lazy or busy mode. And to put the default setting back, it's WindowShadeLazy. โœจ

ResizeOpaque instructs fvwm to resize the corresponding windows with their contents visible instead of using an outline. Sounds cute until you learn that since this causes the application to redraw frequently, it can be quite slow and make the window flicker excessively โ€” depending on the amount of graphics the application redraws. ๐Ÿ˜ญ The ResizeOutline style (the default) negates the ResizeOpaque style. And ngl, many applications do not like their windows being resized opaque, e.g. XEmacs, Netscape, or terminals with a pixmap background. If you don't like the result, do not use the ResizeOpaque style for these windows. To exempt certain windows from opaque resizing, you could use these lines in your configuration file:

Style * ResizeOpaque
Style rxvt ResizeOutline
Style emacs ResizeOutline

Sticky makes the window sticky, i.e. it is always visible on each page and each desk. The opposite style, Slippery, reverts back to the default.

StickyIcon makes the window sticky when it's iconified. It de-iconifies on top the active desktop. SlipperyIcon reverts back to the default.

StickyAcrossPages and StickyAcrossPagesIcon work like Sticky and StickyIcon, but stick the window only across pages, not desks โ€” while StickyAcrossDesks and StickyAcrossDesksIcon work the other way round. ๐Ÿฆ‹


Windows that have been marked as Sticky or StickyAcrossDesks or StickyAcrossPages will have stipples drawn on the titlebar. This can be negated with the !StickyStippledTitle style. The style StickyStippledTitle puts back the stipples where that window has also been marked as Sticky. Heads up though: this is the default style for Sticky windows. Sticky icons will have stipples drawn on the icon title, and that can be disabled in the same way with the !StickyStippledIconTitle style.

Windows with the StartIconic style are shown as icons initially. Note that some applications counteract that by deiconifying themselves, so don't come for fvwm when that happens. The default is to not iconify windows, and it can be set with the StartNormal style.

StickyIcon makes the window sticky when it's iconified. It de-iconifies on top the active desktop. SlipperyIcon reverts back to the default. (yes, the manpage says this one twice. it ate the first time, so we're saying it twice too. ๐Ÿ’…)

StickyIconPage works like StickyIcon, but sticks the icon only across pages, not desks โ€” while StickyIconDesk works the other way round.

StippledIconTitle works like StippledTitle in that it draws stipples on the titles of icons, but it doesn't make the icon sticky. That's it, that's the whole vibe.

IgnoreRestack makes fvwm ignore attempts of clients to raise or lower their own windows. By default, the opposite style, AllowRestack, is active.

FixedPosition and FixedUSPosition make fvwm ignore attempts of the user to move the window. It's still possible to move the window by resizing it, so it's not a total lockdown. To allow the user to move windows, use the VariablePosition or VariableUSPosition style.

FixedSize and FixedUSSize make fvwm ignore attempts of the user to resize the window. To allow the user to resize windows, use the VariableSize or VariableUSSize style.

FixedPPosition and FixedPSize make fvwm ignore attempts of the program to move or resize its windows. To allow this kind of actions, use the VariablePPosition or VariablePSize style. Fair warning bestie: these styles may sometimes affect the initial placement and dimensions of new windows (depending on the application). If windows are created at strange places, try either the VariablePPosition or !UsePPosition styles. And the FixedPSize style may screw up window dimensions for some applications โ€” Do Not use this style in this case. ๐Ÿšจ

MoveByProgramMethod affects how fvwm reacts to requests by the application to move its windows. By default, fvwm tries to detect which method to use, but it sometimes detects the wrong method. ๐Ÿ˜ญ You may come across a window that:

  • travels across the screen by a few pixels when the application resizes it
  • moves to a screen border with the frame decorations off screen
  • remembers its position for the next time it starts but appears in a slightly shifted position
  • or that attempts to become full screen but has the. (and yeah, that's literally where the sentence ends in the original. sending thoughts and prayers ๐Ÿซถ)

Try out both options, UseGravity and IgnoreGravity, on the window (and that window only) and see if that helps. By default, fvwm uses the AutoDetect method. Once the method was detected, it is never changed again. As long as fvwm can not detect the proper method, it uses IgnoreGravity. To force fvwm to retry the detection, use one of the other two options first and then use AutoDetect again.

Note: This option was introduced to alleviate a problem with the ICCCM specification. The ICCCM clearly states that the UseGravity option should be used, but traditionally applications ignored this rule. (rude of them honestly.)

Closable enables the functions Close, Delete and Destroy to be performed on the windows. This is on by default. The opposite, !Closable, inhibits the window to be closed.

Iconifiable enables the function Iconify to be performed on the windows. This is on by default. The opposite, !Iconifiable, inhibits the window from being iconified.

Maximizable enables the function Maximize to be performed on the windows. This is on by default. The opposite, !Maximizable, inhibits the window from being maximized.

AllowMaximizeFixedSize enables the function Maximize to be performed on windows that are not resizable, unless maximization has been disabled either using the style !Maximizable or through WM hints. This is on by default. The opposite, !AllowMaximizeFixedSize, inhibits all windows that are not resizable from being maximized.

ResizeHintOverride instructs fvwm to ignore the program supplied minimum and maximum size as well as the resize step size (the character size in many applications). This can be handy for broken applications that refuse to be resized. Do not use it if you do not need it, fr fr. The default (opposite) style is NoResizeOverride.

MinWindowSize [ width [ p | c ] height [ p | c ] ] tells fvwm the minimum width and height of a window. The values are the percentage of the total screen area. If the letter p is appended to either of the values, the numbers are interpreted as pixels. If the letter c is appended to either of the values, the numbers are in terms of the client window's size hints โ€” which can be useful for windows such as terminals to specify the number of rows or columns. This command is useful to deal with windows that freak out if their window becomes too small. ๐Ÿ˜ค If you omit the parameters or their values are invalid, both limits are set to 0 pixels (which is the default value).

MaxWindowSize [ width [ p | c ] height [ p | c ] ] tells fvwm the maximum width and height of a window. The values are the percentage of the total screen area. If the letter p is appended to either of the values, the numbers are interpreted as pixels. If the letter c is appended to either of the values, the numbers are in terms of the client window's size hints, which can be useful for windows such as terminals to specify the number of rows or columns. This command is useful to force large application windows to be fully visible. Neither height nor width may be less than 100 pixels. If you omit the parameters or their values are invalid, both limits are set to 32767 pixels (which is the default).

With IconifyWindowGroups all windows in the same window group are iconified and deiconified at once when any window in the group is (de)iconified. The default is IconifyWindowGroupsOff, which disables this behavior. And like, although a number of applications use the window group hint, it is rarely used in a proper way, so it is probably best to use IconifyWindowGroups only for selected applications. ๐Ÿ™ˆ

The option SnapAttraction affects interactive window movement: if during an interactive move the window or icon comes within proximity pixels of another the window or icon, it is moved to make the borders adjoin. The default of 0 means that no snapping happens. Calling this command without arguments turns off snap attraction and restores the default behavior. Please refer also to the SnapGrid option. โœจ

The second argument is optional and may be set to one of the five following values:

  • All โ€” both icons and windows snap to other windows and other icons.
  • SameType โ€” lets windows snap only to windows, and icons snap only to icons.
  • Windows โ€” windows snap only to other windows.
  • Icons โ€” icons snap only to other icons.
  • None โ€” no snapping takes place.

This option can be useful in conjunction with the third argument if you only want to snap against the screen edges. The default behavior is All.

The third and last optional argument may be set to one of the four following values:

  • Screen โ€” the already snapping icons or windows, which is controlled by the second argument, will snap now also to the screen edges.
  • ScreenWindows โ€” snaps only windows to the screen edges.
  • ScreenIcons โ€” snaps only icons to the screen edges.
  • ScreenAll โ€” snaps windows and icons to the screen edges.

The option SnapGrid defines an invisible grid on the screen. During an interactive move a window or icon is positioned such that its location (top left corner) is coincident with the nearest grid point. The default x-grid-size and y-grid-size setting are both 1, which is effectively no grid all. ๐ŸŒˆ

Okay so when you do an interactive move with both SnapGrid and SnapAttraction on? The window gets moved so it's adjacent to the nearest window border (if it's within snap proximity) or to the nearest grid position. It travels the shortest distance possible to satisfy both at once. And bestie, the x and y coordinates are not coupled โ€” they're doing their own thing ๐Ÿ’…. So like, a window can snap to another window along the x axis while simultaneously snapping to a grid point along the y axis. And if you use this style with no arguments at all? It just reinstates the default settings. Slay.

The EdgeMoveDelay and EdgeResizeDelay styles decide how hard it is to change the desktop viewport by moving or resizing a window over the edge of the screen. The parameter tells you how many milliseconds the pointer has to just... sit there on the screen edge before fvwm moves the viewport. The EdgeScroll command decides how far the viewport gets scrolled. If you hand it -1 as the delay, page flipping is completely disabled, no cap. The defaults are no delay for moving (0) and no flipping for resizing (-1). Using these styles without any argument restores the default settings. Also note: even with

EdgeScroll 0 0

you can still move or resize windows across the edge of the current screen. See also EdgeThickness.

The option EdgeMoveResistance makes it easier to place a window directly adjacent to a RandR screen's edge. It takes one or two parameters. The first parameter tells how many pixels over an outside edge of the screen a window's edge has to move before it actually moves partially off the screen. The optional second parameter does the same thing as the first, but for inside edges (that's a shared edge between two RandR monitors, iykyk). If you omit it, there's no resistance between inside edges. Note that the center of the window being moved determines the screen on which the window should be kept. Both values are 0 (no resistance) by default, and to restore the defaults you can just use EdgeMoveResistance with no parameters at all.

The option InitialMapCommand lets any valid fvwm command or function run when the window is initially mapped by fvwm. Example:

Style MyWindow StartsOnPage 0 0, InitialMapCommand Iconify

So this would place the window called MyWindow on page 0 0 for the current desk, and immediately run the Iconify command on that window. Iconic behaviour honestly.

Note that if InitialMapCommand is used as a global option for all windows, but you need some windows to not have this command applied, then an action of Nop can be used on those windows, like this:

Style * InitialMapCommand Iconify
Style XTeddy InitialMapCommand Nop

โœจ Window Manager placement โœจ

Applications can place windows at a particular spot on the screen either by window manager hints or a geometry specification. When they do neither? That's when the window manager steps in to find a place for the window. Fvwm knows several ways to deal with this situation. The default is TileCascadePlacement. ๐Ÿซถ

  • PositionPlacement [Center|UnderMouse|move-arguments] โ€” when used with no argument, new windows get placed in the top left corner of the display. With the argument Center, all new windows appear at the center of the screen, and with UnderMouse, windows are centered under the mouse pointer where possible. If the window can't fit on the screen because the pointer is at the edge of the screen, then the window is forced on-screen using this option. If any other move-arguments are given, they're interpreted exactly as the Move command does (with the exception that references to the current window position do not work, because the window hasn't been placed yet).
  • CascadePlacement โ€” automatically places new windows in a cascading fashion.
  • TileCascadePlacement โ€” automatically places new windows in a smart location, meaning a location where they don't overlap any other windows on the screen. If no such position can be found, CascadePlacement is used as a fall-back method.
  • TileManualPlacement โ€” this is the same as TileCascadePlacement, but it uses ManualPlacement as the fall-back method.
  • MinOverlapPlacement โ€” automatically places new windows in a location where the overlapping area in pixels of other windows is minimized. By default this placement policy tries to avoid overlapping icons and windows on higher layers. You can configure this with the MinOverlapPlacementPenalties style.
  • MinOverlapPercentPlacement โ€” similar to MinOverlapPlacement but it tries to minimize the overlapped percentages of other windows instead of the overlapped area in pixels. This placement policy tries to avoid covering other windows completely, and it tries even harder not to cover small windows. ๐Ÿฅบ Configure it with the MinOverlapPlacementPenalties and MinOverlapPercentPlacementPenalties styles.

MinOverlapPlacementPenalties takes at most 6 positive or null decimal arguments:

normal ontop icon sticky below strut

If trailing arguments are missing, the default is used, which is:

1 5 10 1 0.05 50

To reset this style to the default values, prefix it with a '!'. This style configures the MinOverlapPlacement and MinOverlapPercentPlacement placement policy. The normal factor affects normal windows, the ontop factor affects windows with a greater layer than the window being placed, the icon factor affects icons, the sticky factor affects sticky windows, the below factor affects windows with a smaller layer than the window being placed, and the strut factor affects the complement of the EWMH working area if the window being placed has the EWMHPlacementUseWorkingArea style, and windows with an EWMH strut hint (i.e., a "please do not cover me" hint ๐Ÿ™ˆ) if the window being placed has the EWMHPlacementUseDynamicWorkingArea style. These factors represent the amount of area that these types of windows (or area) are counted as when a new window is placed. For example, by default the area of ontop windows is counted 5 times as much as normal windows. So MinOverlapPlacement and MinOverlapPercentPlacement cover 5 times as much area of another window before they'll cover an ontop window. To treat ontop windows the same as other windows, set this to 1. To really, really avoid putting windows under ontop windows, set this to a high value, say 1000. ๐Ÿ‘‘

This style affects the window already mapped, and not the window which is currently placed. There's one exception to this rule: in the case of the window being placed having the EWMHPlacementUseWorkingArea style, the strut factor affects the placed window.

MinOverlapPercentPlacementPenalties takes at most 4 positive or null integer arguments:

cover_100 cover_95 cover_85 cover_75

If trailing arguments are missing, the defaults are used, which are:

12 6 4 1

To reset this style to the default values, prefix it with a '!'. This style affects the MinOverlapPercentPlacement placement policy and is similar to the MinOverlapPlacementPenalties style. The cover_xx factor is used when the window being placed covers at least xx percent of the window. This factor is added to the factor determined by the MinOverlapPlacementPenalties style.

ManualPlacement (aka active placement). The user is required to place every new window manually. The window only shows as a rubber band until a place is selected manually. The window is placed when a mouse button or any key except Escape is pressed. Escape aborts manual placement, which places the window in the top left corner of the screen. If mouse button 2 is pressed during the initial placement of a window (respectively Shift and mouse button 1 in case Mwm emulation has been enabled with the Emulate command), the user is asked to resize the window too.

It's possible to define buttons usable to place windows with the Move command and the special context 'P' for placement (see Move command). However, you can't redefine the way to also resize the window other than the way it is affected by the Emulate command. The button used for placing the window can be checked with the PlacedByButton condition (see Current command).

Example:

Style * ManualPlacement

*FvwmEvent: PassID
*FvwmEvent: add_window GrowDownFunc
AddToFunc StartFunction
+ I FvwmEvent

AddToFunc GrowDownFunc
+ I windowid $0 (PlacedByButton 3) \
Resize bottomright keep -0p

Now, whenever a window is created and the user presses button 3 to finish initial placement, the window is automatically enlarged until it hits the bottom screen border. The way that ate. ๐Ÿ”ฅ

Old placement styles DumbPlacement / SmartPlacement / SmartPlacementOff, CleverPlacement / CleverPlacementOff, ActivePlacement / RandomPlacement, ActivePlacementsHonorsStartsOnPage / ActivePlacementsHonorsStartsOnPageOff are still supported but will be removed in the future. Bestie, they're on their way out. ๐Ÿ˜ญ

The old and new styles can be translated according to the following table:

Style * DumbPlacement, RandomPlacement
-->
Style * CascadePlacement

Style * DumbPlacement, ActivePlacement
-->
Style * ManualPlacement

Style * SmartPlacement, \
RandomPlacement, CleverPlacementOff
-->
Style * TileCascadePlacement

Style * SmartPlacement, \
ActivePlacement, CleverPlacementOff
-->
Style * TileManualPlacement

Style * SmartPlacement, CleverPlacement
-->
Style * MinOverlapPlacement

Style * SmartPlacement, \
ActivePlacement, CleverPlacement
-->
Style * MinOverlapPercentPlacement

Style * ActivePlacementsHonorsStartsOnPage
-->
Style * ManualPlacementsHonorsStartsOnPage

Style * ActivePlacementsHonorsStartsOnPageOff
-->
Style * ManualPlacementsHonorsStartsOnPageOff

๐ŸŒˆ Placement policy options and window stacking ๐ŸŒˆ

!UsePPosition instructs fvwm to ignore the program specified position (the PPosition hint) when adding new windows. Using PPosition is required for some applications, but if you don't have one of those, it's a real headache. ๐Ÿ’€ Many programs set PPosition to something obnoxious like 0,0 (upper left corner). Note: !UsePPosition is equivalent to the deprecated option !UsePPosition.

  • !UseUSPosition โ€” bestie this one works just like !UsePPosition except it suppresses using the position the user specified, the one the program reports via the USPosition hint. Overriding the user's own choice is generally a bad thing, ngl, but some apps misuse the USPosition hint to shove their windows onto a certain spot of the screen without asking. Rude fr. ๐Ÿ’€ Heads up: !UseUSPosition is equivalent to the deprecated option !USPosition.
  • NoUseTransientPPosition and UseTransientPPosition โ€” same energy as !UsePPosition and UsePPosition, but they only apply to transient windows. โœจ Note: !UseTransientPPosition is equivalent to the deprecated option !TransientPPosition.
  • NoUseIconPosition โ€” tells fvwm to straight up ignore the icon position the program specified (the IconPosition hint) when it iconifies the window. Note: !UseIconPosition is equivalent to the deprecated option !IconPosition.
  • StartsOnDesk โ€” takes one numeric argument, which is the desktop number where the window should first be placed. ๐ŸŽ€ Lowkey important: standard Xt programs can also set this with a resource, like -xrm '*Desk: 1'.
  • StartsOnPage โ€” takes 1, 2, or 3 numeric arguments. Here's the tea:
    • Give it one or three arguments, and the first (or only) one is the desktop number.
    • Give it three, and arguments 2 and 3 are the x,y page position on the virtual window.
    • Give it two, and they're the page position, with no desk preference implied.
    • Give it only one, and StartsOnPage acts exactly like StartsOnDesk.

For those standard Xt programs that get this usage, the starting desk/page can also be set with a resource (e.g. -xrm '*page: 1 0 2'). And pairing StartsOnPage with SkipMapping is such a useful technique when you want to launch an app on another page and just keep doing your thing instead of sitting there waiting for it to show up. ๐Ÿ’…

  • StartsOnScreen โ€” takes one argument, and it must be a valid RandR name. The new window gets placed on that screen. Default behaviour: windows land on the screen that has the mouse pointer at the moment the window is created. BUT โ€” those windows that fvwm doesn't place (i.e. the ones with a USPosition hint from a user-specified geometry) are normally placed at a position relative to all identified screens.
  • StartsOnPageIncludesTransients โ€” makes the StartsOnPage style apply even to transient windows. Usually not that useful, since transients are normally pop ups you want showing up in your visible viewport ๐Ÿซถ, but every so often an app uses a transient for something like a startup window that needs to be coerced into place.
  • ManualPlacementIgnoresStartsOnPage โ€” suppresses StartsOnPage or StartsOnDesk placement when both ManualPlacement and SkipMapping are in effect while a window is being created. This stops you from interactively placing a window and then going "where did it GO" because it got placed on a different desk or page. ๐Ÿ˜ญ
  • ManualPlacementHonorsStartsOnPage โ€” lets that happen anyway. This option does nothing if SkipMapping isn't in effect, because fvwm switches to the proper desk/page to do the interactive placement. The default is ManualPlacementIgnoresStartsOnPage; ManualPlacementHonorsStartsOnPage matches how the old StartsOnDesk style used to handle the situation.
  • CaptureHonorsStartsOnPage โ€” makes the initial capture (of a window that already exists) at startup place the window according to the StartsOnPage and StartsOnScreen desk, page and screen specification. โœจ
  • CaptureIgnoresStartsOnPage โ€” makes fvwm ignore those settings (including StartsOnDesk) on initial capture. This is the default.
  • RecaptureHonorsStartsOnPage โ€” makes a window be placed according to, or revert to, the StartsOnPage and StartsOnScreen desk, page and screen specification on Restart. ๐ŸŒˆ
  • RecaptureIgnoresStartsOnPage โ€” makes fvwm respect the window's current position on Restart. This is the default.
  • Layer โ€” takes one optional argument: a non-negative integer. That's the layer the window gets put in. No argument given? Then any previously set value is deleted and the default layer is implied. ๐ŸŽ€
  • StaysOnTop โ€” puts the window in the top layer. This layer can be changed with the command DefaultLayers; the default is 6.
  • StaysPut โ€” puts the window in the put layer. Changeable with DefaultLayers too; the default is 4.
  • StaysOnBottom โ€” puts the window in the bottom layer. Also DefaultLayers-able; the default is 2.
  • StartsLowered โ€” tells fvwm to put the window initially at the bottom of its layer instead of the default StartsRaised. ๐Ÿ’…
  • StartShaded โ€” tells fvwm to shade the window. You can hand it an optional direction argument, one of "North", "South", "West", "East", "NorthWest", "NorthEast", "SouthWest", "SouthEast". No direction? Default is to shade north. ๐Ÿฆ‹
  • SkipMapping โ€” tells fvwm not to switch to the desk the window is on when it gets mapped initially. Super useful with StartsOnDesk or StartsOnPage.
  • KeepWindowGroupsOnDesk โ€” makes new windows that have the window group hint set appear on the same desk as the other windows in the same group. Since this behaviour may be confusing, the default setting is ScatterWindowGroups. The window group hint is ignored when placing windows in this case. ๐Ÿ™ˆ

Transient windows

  • DecorateTransient โ€” causes transient windows, which are normally left undecorated, to get the usual fvwm decorations (title bar, buttons, etc.). Note that some pop-up windows, like the xterm menus, are not managed by the window manager and still don't receive decorations. ๐Ÿซถ
  • NakedTransient โ€” the default, causes transient windows not to get the standard decorations. You can only bind keys or mouse buttons to the sides and the client part of an undecorated window ('S' and 'W' contexts in bindings โ€” see the Mouse and Key commands).
  • RaiseTransient โ€” a window with this style that has transient windows raises all its transients when it is raised. ๐Ÿ”ฅ
  • DontRaiseTransient โ€” disables that behaviour. All windows are then treated as if they had no transients.
  • LowerTransient โ€” a window with this style that has transient windows lowers all its transients when it is lowered.
  • DontLowerTransient โ€” disables that behaviour. All windows are then treated as if they had no transients.
  • StackTransientParent โ€” augments the RaiseTransient and LowerTransient styles. Raising a window with the StackTransientParent style transfers the raise action to the main window if the window being raised is a transient and its main window has RaiseTransient style; this effect makes raise on a transient act just like raise on its main โ€” the whole group gets raised. Same vibe holds for lowering a whole group of transients when the main has LowerTransient style. ๐Ÿ‘‘
  • DontStackTransientParent โ€” turns this behaviour off. (Dont)StackTransientParent has no effect if RaiseTransient and LowerTransient aren't used.

A reasonable emulation of Motif raise/lower on transients is possible like this:

Style * RaiseTransient
Style * LowerTransient
Style * StackTransientParent

Extended Window Manager Hints styles

To understand the terminology used in this sub section, please go read the Extended Window Manager Hints section. ๐Ÿ“–

  • EWMHDonateIcon โ€” instructs fvwm to set the application ewmh icon hint with the icon that fvwm uses, if the application doesn't provide such a hint (and if the icon fvwm uses is not an icon window).
  • EWMHDonateMiniIcon โ€” does the same thing for mini icons. This lets compliant pagers, taskbars, iconboxes... etc. display the same (mini) icons as fvwm. โœจ Note that on some hardware (e.g. 8-bit displays) these styles can slow down window mapping, and that in general only one of these styles is needed by a compliant application.
  • EWMHDontDonateIcon and EWMHDontDonateMiniIcon โ€” restore the defaults, which are to not set any ewmh (mini) icons hints.
  • EWMHMiniIconOverride โ€” by default, if an application provides an ewmh icon hint of small size (i.e., height and width less than or equal to 22), then fvwm uses this icon as its mini icon. This style instructs fvwm to ignore ewmh icons and use the mini icon provided by the MiniIcon style instead. ๐ŸŽ€
  • EWMHNoMiniIconOverride โ€” restores the default.
  • EWMHUseStackingOrderHints โ€” causes fvwm to use EWMH hints and respect EWMH hints which change the window layer.
  • EWMHIgnoreStackingOrderHints โ€” causes fvwm to ignore EWMH layer hints.
  • EWMHUseStrutHints / EWMHIgnoreStrutHints โ€” an application can ask for some reserved space on the desktop via a hint. In EWMH terminology such a hint is called a strut, and it's used to compute the working area and may be used for window placement and in the Maximize command. EWMHIgnoreStrutHints causes fvwm to ignore such hints, while EWMHUseStrutHints causes fvwm to use it โ€” which is the default. ๐Ÿ’…
  • EWMHIgnoreStateHints โ€” causes fvwm to ignore initial EWMH state hints when a new window is mapped.
  • EWMHUseStateHints โ€” the default, causes fvwm to accept such hints.
  • EWMHIgnoreWindowType โ€” causes fvwm to ignore EWMH window type specification.
  • !EWMHIgnoreWindowType โ€” the default, causes fvwm to style windows of specified types as such.
  • EWMHMaximizeIgnoreWorkingArea โ€” causes fvwm to ignore the EWMH working area when it executes a Maximize command. ๐ŸŒธ
  • EWMHMaximizeUseWorkingArea โ€” the EWMH working area is used.
  • EWMHMaximizeUseDynamicWorkingArea โ€” the EWMH dynamic working area is used. This is the default.
  • EWMHPlacementIgnoreWorkingArea โ€” causes fvwm to ignore the EWMH working area when it places (or places again) a window.
  • EWMHPlacementUseWorkingArea โ€” the EWMH working area is taken into account.
  • EWMHPlacementUseDynamicWorkingArea โ€” the EWMH dynamic working area is taken into account. This is the default. ๐ŸŒˆ
Note that with the MinOverlapPlacement and MinOverlapPercentPlacement placement policy, the way the EWMH (dynamic) working area is taken into account is configurable with the MinOverlapPlacementPenalties style. ๐Ÿซถ

๐ŸŒธ Miscellaneous ๐ŸŒธ

Okay bestie, these are the lil style extras that don't fit anywhere else. Buckle up. ๐Ÿ’–

  • BackingStore, BackingStoreOff and BackingStoreWindowDefault decide whether the X server uses backing store for the window or not. BackingStore means the X server tries to keep the obscured parts of a window in memory. This is usually slower if the client runs on the same machine as the X server, but it can be much faster if the connection is slow (see also SaveUnder below). BackingStoreOff disables backing store for the window. By default, fvwm does not enable or disable backing store itself but leaves it as the window requested it. To revert back to the application's choice, use the BackingStoreWindowDefault style.
Note: this style is useless if the X server does not allow backing store. ๐Ÿ’€
  • SaveUnder enables the corresponding window attribute in the X server. For a window using this style, the X server tries to store the graphics below it in memory, which is usually slower if the client runs on the same machine as the X server. SaveUnder may speed up fvwm if the connection to the X server is slow (e.g. over a modem link ๐Ÿซ ). To disable save under, use the SaveUnderOff style. This is the default. See also BackingStore above.
Note: this style is useless if the X server does not allow save under. Same energy as above, no cap.
  • ParentalRelativity enables clients that use a background pixmap of type ParentRelative to achieve transparency. Fvwm modules that support transparent colorsets require this setting. Opacity is the default and should be used for all non-transparent clients for better performance. โœจ
  • MwmDecor makes fvwm attempt to recognize and respect the mwm decoration hints that applications occasionally use. To switch this style off, use the NoDecorHint style.
  • MwmFunctions makes fvwm attempt to recognize and respect the mwm prohibited operations hints that applications occasionally use. HintOverride makes fvwm shade out operations that mwm would prohibit, but it lets you perform the operation anyway. NoFuncHint allows turns off the mwm hints completely. ๐ŸŽ€
  • OLDecor makes fvwm attempt to recognize and respect the olwm and olvwm hints that many older XView and OLIT applications use. Switch this option off with NoOLDecor.
  • UseDecor โ€” โš ๏ธ this style is deprecated and will be removed in the future. There are plans to replace it with a more flexible solution in fvwm-3.0.

UseDecor accepts one argument: the name of a decor created with AddToDecor. If no decor name is specified, the "Default" decor is used. Windows do not actually contain decors, but are always assigned to one. If the decor is later modified with AddToDecor, the changes are visible for all windows which are assigned to it. The decor for a window can be reassigned with ChangeDecor.

  • UseStyle โ€” โš ๏ธ also deprecated, also getting removed in the future, also planned to be replaced with a more flexible solution in fvwm-3.0.

UseStyle takes one arg, which is the name of another style. That way you can have unrelated window names easily inherit similar traits without retyping. For example:

Style rxvt UseStyle XTerm
Warning: if a style is built from one or more parent styles and the parent styles are changed, the derived style is not modified. To achieve this you have to issue the UseStyle line again. Annoying? yes. Iconic? also yes. ๐Ÿ˜ญ
  • Unmanaged โ€” windows with the Unmanaged style option are ignored by fvwm. They are not decorated, can not be moved or resized, etc. You probably want to use Bugopts RaiseOverUnmanaged too. This option can be turned off with the !Unmanaged style.
  • State sets the initial value of one of the 32 user defined states which are associated with each window. The state number ranges from 0 to 31 and must be given as an argument. The states have no meaning in fvwm, but they can be checked in conditional commands like Next with the State condition and manipulated with the State command.
# turn on state 11 for xterms ...
Style xterm State 11
# ... but not for rxvts.
Style rxvt !State 11
  • WindowListSkip โ€” windows with the WindowListSkip styles do not appear in the menu that is created with the WindowList command or the lists shown in modules like FvwmIconMan. In the modules, the style can usually be ignored with an option. Please refer to the man page of the module in question for further information. To disable this feature, use the default style WindowListHit.
  • CirculateSkip and CirculateHit control whether the window is considered by conditional commands, for example Next, Prev or All. Windows with CirculateSkip are never selected by conditional commands. However, the styles can be overridden explicitly in the condition with the CirculateHit, CirculateHitIcon or CirculateHitShaded conditions, and some conditional commands, e.g. Current and All, do this by default. The styles CirculateSkipIcon, CirculateHitIcon, CirculateSkipShaded and CirculateHitShaded work like CirculateSkip and CirculateHit but apply only to iconic or shaded windows.
Note: if multiple ...Skip... options are combined, windows are only selected if they match none of the given conditions. So, with
Style * CirculateSkipIcon, CirculateSkipShaded
only windows that are neither iconic nor shaded are selected.
Note: for historical reasons, the conditional commands understand the names of these styles as condition names. Take care not to confuse them. ๐Ÿซ 

๐Ÿฆ‹ Examples ๐Ÿฆ‹

# Change default fvwm behavior to no title-
# bars on windows! Also define a default icon.

Style *       !Title,                      \
              Icon unknown1.xpm,           \
              BorderWidth 4,               \
              HandleWidth 5

# now, window specific changes:
Style Fvwm* !Handles, Sticky,              \
            WindowListSkip,                \
            BorderWidth 0
Style FvwmPager   StaysOnTop, BorderWidth 0
Style *lock       !Handles, Sticky,        \
                  StaysOnTop, WindowListSkip
Style xbiff       Sticky, WindowListSkip
Style FvwmButtons !Handles, Sticky,        \
                  WindowListSkip
Style sxpm        !Handles

# Put title-bars back on xterms only!
Style xterm     Title, Color black/grey

Style rxvt        Icon term.xpm
Style xterm       Icon rterm.xpm
Style xcalc       Icon xcalc.xpm
Style xbiff       Icon mail1.xpm
Style xmh         Icon mail1.xpm,         \
                  StartsOnDesk 2
Style xman        Icon xman.xpm
Style matlab      Icon math4.xpm,         \
                  StartsOnDesk 3
Style xmag        Icon magnifying_glass2.xpm
Style xgraph      Icon graphs.xpm
Style FvwmButtons Icon toolbox.xpm
Style Maker       StartsOnDesk 1
Style signal      StartsOnDesk 3

# Fire up Netscape on the second desk, in the
# middle of my 3x3 virtual desktop, and do not
# bother me with it...
Style Netscape* SkipMapping,              \
          StartsOnPage 1 1 1

Note that all properties for a window are or'ed together. In the above example "FvwmPager" gets the property StaysOnTop via an exact window name match but also gets !Handles, Sticky and WindowListSkip by a match to "Fvwm*". It gets !Title by virtue of a match to "*". If conflicting styles are specified for a window, then the last style specified is used. The way that it stacks like that... ๐Ÿ’…

๐Ÿ‘‘ WindowStyle options ๐Ÿ‘‘

sets attributes (styles) on the selected window. The options are exactly the same as for the Style command.


๐ŸŒˆ Window Styles ๐ŸŒˆ

๐Ÿ’– AddButtonStyle ๐Ÿ’–

AddButtonStyle button [state] [style] [-- [!]flag ...]

Adds a button style to button. button can be a button number, or one of "All", "Left" or "Right". state can be "ActiveUp", "ActiveDown", "InactiveUp" or "InactiveDown", or "Active" (the same as both "ActiveUp" and "ActiveDown") or "Inactive" (the same as both "InactiveUp" and "InactiveDown") or any of these 6 with "Toggled" prepended. The "Active" states apply to the focused window, the "Inactive" ones apply to all other windows. The "Up" states apply to the non pressed buttons, the "Down" ones apply to pressed buttons. The "Toggled" prefix refers to maximized, shaded or sticky windows that have the corresponding MwmDecor... button style set. โœจ

Additionally, the following shortcuts may be used: "AllNormal", "AllToggled", "AllActive", "AllInactive", "AllUp", "AllDown". They are actually different masks for 4 individual states from 8 total. These are supported too: "AllActiveUp", "AllActiveDown", "AllInactiveUp", "AllInactiveDown". ๐Ÿ”ฅ

If state is omitted, then the style is added to every state. If the style and flags are enclosed in parentheses, then multiple state definitions can be placed on a single line. Flags for additional button styles cannot be changed after definition. ๐Ÿซถ

Buttons are drawn in the order of definition, beginning with the most recent button style, followed by those added with AddButtonStyle. To clear the button style stack, change style flags, or for descriptions of available styles and flags, see the ButtonStyle command.

Examples:

**ButtonStyle** 1 Pixmap led.xpm -- Top Left
**ButtonStyle** 1 ActiveDown HGradient 8 grey black
**ButtonStyle All** --  UseTitleStyle
AddButtonStyle 1 \
        ActiveUp (Pixmap a.xpm) \
        ActiveDown (Pixmap b.xpm -- Top)
AddButtonStyle 1 Vector 4 50x30@1 70x70@0 30x70@0 50x30@1

Initially for this example all button states are set to a pixmap. The second line replaces the "ActiveDown" state with a gradient (it overrides the pixmap assigned to it in the line before, which assigned the same style to every state). Then, the UseTitleStyle flag is set for all buttons, which causes fvwm to draw any styles set with TitleStyle before drawing the buttons. Finally, AddButtonStyle is used to place additional pixmaps for both "ActiveUp" and "ActiveDown" states and a vector button style is drawn on top of all states. Ate, honestly. ๐ŸŽ€

๐Ÿ’– AddTitleStyle ๐Ÿ’–

AddTitleStyle [state] [style] [-- [!]flag ...]

okay bestie so this one adds a title style to the title-bar โœจ

  • state can be "ActiveUp", "ActiveDown", "InactiveUp" or "InactiveDown", or "Active" (which is literally the same as both "ActiveUp" and "ActiveDown"), or "Inactive" (same as both "InactiveUp" and "InactiveDown"), or any of these 6 with "Toggled" slapped on the front ๐Ÿ‘‘
  • if state is justโ€ฆ not there? then the style gets added to every state, no cap ๐Ÿซถ
  • if the style and flags are wrapped in parentheses, you can put multiple state definitions on a single line, which is giving efficiency honestly
  • this command is quite similar to the AddButtonStyle command ๐Ÿ’…

Title-bars are drawn in the order of definition, beginning with the most recent TitleStyle, followed by those added with AddTitleStyle. To clear the title style stack, change style flags, or for the descriptions of available styles and flags, see the TitleStyle and ButtonStyle commands. iykyk ๐ŸŒธ


๐ŸŒˆ AddToDecor ๐ŸŒˆ

AddToDecor decor
โš ๏ธ okay so this command is deprecated and will be removed in the future. There are plans to replace it with a more flexible solution in fvwm-3.0. so likeโ€ฆ use it knowing that, bestie ๐Ÿ’€

Add or divert commands to the decor named decor. A decor is a name given to the set of commands which affect button styles, title-bar styles and border styles. If decor does not exist it is created; otherwise the existing decor is modified. โœจ

New decors start out exactly like the "default" decor without any style definitions. A given decor may be applied to a set of windows with the UseDecor option of the Style command. Modifying an existing decor affects all windows which are currently assigned to it. ๐Ÿฆ‹

AddToDecor is similar in usage to the AddToMenu and AddToFunc commands, except that menus and functions are replaced by ButtonStyle, AddButtonStyle, TitleStyle, AddTitleStyle and BorderStyle commands. Decors created with AddToDecor can be manipulated with ChangeDecor, DestroyDecor, UpdateDecor and the Style option. ๐Ÿ‘‘

The following example creates a decor "FlatDecor" and style "FlatStyle". They are distinct entities:

AddToDecor FlatDecor
+ ButtonStyle All Active (-- flat) Inactive (-- flat)
+ TitleStyle  -- flat
+ BorderStyle -- HiddenHandles NoInset

Style FlatStyle \
        UseDecor FlatDecor, HandleWidth 4, Colorset 0

Style xterm UseStyle FlatStyle

An existing window's decor may be reassigned with ChangeDecor. A decor can be destroyed with DestroyDecor. ๐Ÿงš

DestroyDecor FlatDecor
AddToDecor FlatDecor ...

Style FlatStyle UseDecor FlatDecor

and now apply the style again:

Style xterm UseStyle FlatStyle

๐Ÿ’… BorderStyle ๐Ÿ’…

BorderStyle state [style] [-- [!]flag ...]

Defines a border style for windows. state can be either "Active" or "Inactive". If state is omitted, then the style is set for both states. If the style and flags are enclosed in parentheses, then multiple state definitions can be specified per line. ๐ŸŒŸ

style is a subset of the available button styles, and can only be TiledPixmap (uniform pixmaps which match the bevel colors work best this way) or Colorset. If a ! is prefixed to any flag, the behavior is negated. If style is not specified, then one can change flags without resetting the style. ๐Ÿ”ฅ

The HiddenHandles flag hides the corner handle dividing lines on windows with handles (this option has no effect for !Handles windows). By default, HiddenHandles is disabled. ๐Ÿ’€

The NoInset flag supplements HiddenHandles. If given, the inner bevel around the window frame is not drawn. If HiddenHandles is not specified, the frame looks a little strange. ๐Ÿ™ˆ

  • Raised causes a raised relief pattern to be drawn (default).
  • Sunk causes a sunken relief pattern to be drawn.
  • Flat inhibits the relief pattern from being drawn.

To decorate the active and inactive window borders with a textured pixmap, one might specify:

BorderStyle Active TiledPixmap marble.xpm
BorderStyle Inactive TiledPixmap granite.xpm
BorderStyle Active -- HiddenHandles NoInset

To clear the style for both states:

BorderStyle Simple

To clear for a single state:

BorderStyle Active Simple

To unset a flag for a given state:

BorderStyle Inactive -- !NoInset

title-bar buttons can inherit the border style with the UseBorderStyle flag (see ButtonStyle). ๐Ÿ’–


โœจ ButtonState โœจ

ButtonState [ActiveDown bool] [Inactive bool] [InactiveDown bool]

The ButtonState command controls which states of the window titles and title buttons are used. The default is to use all four states: "ActiveUp", "ActiveDown", "InactiveUp" and "InactiveDown" (see ButtonStyle and TitleStyle commands). ๐Ÿ‘‘

The bool argument after the key word controls if the designated state is used ("True") or not ("False"). The bool flag is the same as other commands, and not limited to just "True" or "False"; "Yes" and "No" may also be used. The "ActiveUp" state cannot be deactivated. If no arguments are provided or the given arguments are invalid, the default is restored. ๐Ÿฆ‹

  • If ActiveDown argument is "False", no different button style for the pressed down buttons used, instead "ActiveUp" state is used even when button is pressed.
  • If Inactive argument is "False", focused and unfocused windows look similarly, the corresponding "Active" states are always used.
  • If InactiveDown argument is "False" (only applied when Inactive is "True"), the pressed titles and title buttons in non-focused windows are drawn using "InactiveUp" or "ActiveUp" states depending on the values of the other key words. ๐Ÿ’œ

๐ŸŽ€ ButtonStyle ๐ŸŽ€

ButtonStyle button [state] [style] [-- [!]flag ...]

Sets the button style for a title-bar button. button is the title-bar button number between 0 and 9, or one of "All", "Left", "Right", or "Reset". Button numbering is described in the Mouse command section. If the style and flags are enclosed in parentheses, then multiple state definitions can be specified per line. ๐Ÿ”ฅ

state refers to which button state should be set. Button states are defined as follows: "ActiveUp" and "ActiveDown" refer to the un-pressed and pressed states for buttons on active windows; while the "InactiveUp" and "InactiveDown" states denote buttons on inactive windows. The shortcut "Active" denotes both "ActiveUp" and "ActiveDown" states. Shortcut "Inactive" denotes both "InactiveUp" and "InactiveDown" states. The similar state names like just described, but with the "Toggled" prefix are used instead for title buttons which have one of the MwmDecorMax, MwmDecorShade, MwmDecorStick or MwmDecorLayer hints, if the window is maximized, shaded, sticky or placed on specific layer, respectively. โœจ

AddToDecor Default
+ ButtonStyle 6                   \
  Vector 4 50x25@1 85x75@0 15x75@0 50x25@1
+ ButtonStyle 6 ToggledActiveUp   \
  Vector 4 50x75@0 85x25@1 15x25@0 50x75@0
+ ButtonStyle 6 ToggledActiveDown \
  Vector 4 50x75@0 85x25@1 15x25@0 50x75@0
+ ButtonStyle 6 ToggledInactive   \
  Vector 4 50x75@0 85x25@1 15x25@0 50x75@0
+ ButtonStyle 6 - MwmDecorShade
Mouse 0 6 N WindowShade

Additionally, the following shortcuts may be used: "AllNormal", "AllToggled", "AllActive", "AllInactive", "AllUp", "AllDown". They are actually different masks for 4 individual states from 8 total. These are supported too: "AllActiveUp", "AllActiveDown", "AllInactiveUp", "AllInactiveDown". ๐ŸŒˆ

If state is specified, that particular button state is set. If state is omitted, every state is set. Specifying a style destroys the current style (use AddButtonStyle to avoid this). ๐Ÿ’…

If style is omitted, then state-dependent flags can be set for the primary button style without destroying the current style. Examples (each line should be considered independent):

ButtonStyle Left -- flat
ButtonStyle All ActiveUp (-- flat) Inactive (-- flat)

The first line sets every state of the left buttons to flat, while the second sets only the "ActiveUp" and "Inactive" states of every button to flat (only flags are changed; the buttons' individual styles are not changed). ๐Ÿซถ

If you want to reset all buttons to their defaults:

ButtonStyle Reset

To reset the "ActiveUp" button state of button 1 to the default:

ButtonStyle 1 ActiveUp Default

To reset all button states of button 1 to the default of button number 2:

ButtonStyle 1 Default 2

For any button, multiple state definitions can be given on one line by enclosing the style and flags in parentheses. If only one definition per line is given the parentheses can be omitted. ๐ŸŒŸ

flags affect the specified state. If a ! is prefixed to any flag, its behavior is negated. The available state-dependent flags for all styles are described here (the ButtonStyle entry deals with state-independent flags). ๐Ÿ‘‘

  • Raised โ€” causes a raised relief pattern to be drawn.
  • Sunk โ€” causes a sunken relief pattern to be drawn.
  • Flat โ€” inhibits the relief pattern from being drawn.
  • UseTitleStyle โ€” causes the given button state to render the current title style before rendering the buttons' own styles. The Raised, Flat and Sunk TitleStyle flags are ignored since they are redundant in this context.
  • UseBorderStyle โ€” causes the button to inherit the decorated BorderStyle options.

Raised, Sunk and Flat are mutually exclusive, and can be specified for the initial ButtonStyle only. UseTitleStyle and UseBorderStyle are also mutually exclusive (both can be off however). The default is Raised with both UseBorderStyle and UseTitleStyle left unset. ๐Ÿ’–

### ๐Ÿ˜ญ Important ๐Ÿ˜ญ for the "ActiveDown" and "InactiveDown" states: when a button is pressed, the relief is inverted. Because of this, to obtain the raised look in "ActiveDown" or "InactiveDown" states you must specify the opposite of the desired relief (i.e. Sunk for "ActiveDown" or "InactiveDown"). This behavior is consistent, but may seem confusing at first. The same applies to the "Toggled" states. ๐Ÿ’€

Button styles are classified as non-destructive, partially destructive, or fully destructive. Bestie, this matters, okay?

  • Non-destructive styles do not touch the image at all. Untouched. Pristine. โœจ
  • Partially destructive styles can obscure some or all parts of the underlying image (i.e. Pixmap). Rude of them.
  • Fully destructive styles obscure the entire underlying image (i.e. Solid or one of the gradient styles). Nothing survives. ๐Ÿ’€

So if you're stacking styles with AddButtonStyle (or AddTitleStyle for title-bars), use care in sequencing styles to minimize redraw. Order is literally everything, iykyk. ๐ŸŽ€

The available styles are:

Simple, Default, Solid, Colorset, Vector, ?Gradient, Pixmap, AdjustedPixmap, ShrunkPixmap, StretchedPixmap, TiledPixmap, MiniIcon

The description of these styles and their arguments follow:


Simple ๐ŸŒธ

The Simple style does nothing. There are no arguments, and this style is an example of a non-destructive button style. It's the chill one. It's just vibing. ๐Ÿฆ‹

Default ๐ŸŽ€

The Default style conditionally accepts one argument: a number which specifies the default button number to load.

  • If the style command given is ButtonStyle or AddButtonStyle, the argument is optional (if given, it overrides the current button).
  • If a command other than ButtonStyle or AddButtonStyle is used, the number must be specified.

Solid ๐Ÿ’…

The Solid style fills the button with a solid color. The relief border color is not affected. The color is specified as a single argument. This style is fully destructive. It ate the whole image, no crumbs. ๐Ÿ˜ญ

Colorset ๐Ÿ“

The Colorset cs [alpha] style fills the button with the Colorset cs. The optional alpha argument is a percentage between 0 and 100. It causes fvwm to merge the colorset background onto the button using this percentage.

  • If the percentage is 0 the colorset background is hidden.
  • If it is 100 the colorset background is fully applied.
  • The default is 100.

So, the destructiveness depends on the alpha argument. It's giving "how much do I want this to take over the look" energy. ๐Ÿ‘‘

Vector ๐Ÿฆ‹

The Vector num X[offsetp]xY[offsetp]@C ... style draws a line pattern.

Since this is a standard button style, the keyword Vector is optional, num is a number of point specifications of the form X[offsetp]xY[offsetp]@C ... X and Y are point coordinates inside the button, given in percents (from 0 to 100). An optional absolute offset in pixels, can be given as "+<offset>p" for a positive or "-<offset>p" for a negative offset.

C specifies a line color:

  • 0 โ€” the shadow color
  • 1 โ€” the highlight color
  • 2 โ€” the background color
  • 3 โ€” the foreground color
  • 4 โ€” only move the point, do not draw

The first point color is not used. You can use up to 10000 points in a line pattern. This style is partially destructive.

The specification is a little cumbersome, ngl:

ButtonStyle 2 Vector 4 50x30@1 70x70@0 30x70@0 50x30@1

then the button 2 decoration uses a 4-point pattern consisting of a line from (x=50,y=30) to (70,70) in the shadow color (@0), and then to (30,70) in the shadow color, and finally to (50,30) in the highlight color (@1). Is that too confusing? ๐Ÿ˜ตโ€๐Ÿ’ซ See the fvwm web pages for some examples with screenshots.

A more complex example of Vector:

ButtonStyle 8 Vector 10 45x65@2 45x75@3 \
20x75@3 20x50@3 35x50@3 35x65@1 35x25@1 \
75x25@1 75x65@0 35x65@0
ButtonStyle 0 Vector 10 45x65@2 45x75@0 \
20x75@0 20x50@1 45x50@1 45x65@0 75x65@3 \
75x25@3 35x25@3 35x47@3

Gradients ๐ŸŒˆ

The Gradient styles denote color gradients. Fill in the question mark with any one of the defined gradient types. Please refer to the Color Gradients section for a description of the gradient syntax. The gradient styles are fully destructive. They take over the whole thing, no cap. ๐Ÿ”ฅ

Pixmap ๐ŸŒธ

The Pixmap style displays a pixmap. A pixmap should be specified as an argument. For example, the following would give button number 2 the same pixmap for all 4 states (2 active and 2 inactive), and button number 4 all different pixmaps.

ButtonStyle 2 Pixmap my_pixmap.xpm
ButtonStyle 4 \
ActiveUp (Pixmap activeup.xpm) \
ActiveDown (Pixmap activedown.xpm) \
Inactive (Pixmap inactiveup.xpm)
ButtonStyle 4 \
InactiveDown Pixmap inactivedown.xpm

The pixmap specification can be given as an absolute or relative pathname (see ImagePath). If the pixmap cannot be found, the button style reverts to Simple. ๐Ÿ˜ญ Flags specific to the Pixmap style are Left, Right, Top, and Bottom. These can be used to justify the pixmap (default is centered for both directions). Pixmap transparency is used for the color "None." This style is partially destructive.

AdjustedPixmap โœจ

The AdjustedPixmap style is similar to the Pixmap style. But the image is resized to exactly fit the button. Snatched to size. ๐Ÿ’…

ShrunkPixmap ๐ŸŽ€

The ShrunkPixmap style is similar to the Pixmap style. But if the image is bigger than the button the image is resized to fit into the button.

StretchedPixmap ๐Ÿฆ‹

The StretchedPixmap style is similar to the Pixmap style. But if the image is smaller than the button the image is resized to cover the button.

TiledPixmap ๐Ÿ“

The TiledPixmap style accepts a pixmap to be tiled as the button background. One pixmap is specified as an argument. Pixmap transparency is not used. This style is fully destructive.

MiniIcon ๐Ÿ‘‘

The MiniIcon style draws the window's miniature icon in the button, which is specified with the MiniIcon option of the Style command. This button style accepts no arguments. Example:

Style *     MiniIcon mini-bx2.xpm
Style xterm MiniIcon mini-term.xpm
Style Emacs MiniIcon mini-doc.xpm

ButtonStyle 1 MiniIcon

ButtonStyle button - [!]flag ... ๐ŸŒˆ

Sets state-independent flags for the specified button. State-independent flags affect button behavior. Each flag is separated by a space. If a '!' is prefixed to the flag then the behavior is negated. The special flag Clear clears any existing flags.

The following flags are usually used to tell fvwm which buttons should be affected by mwm function hints (see MwmFunctions option of the Style command. This is not done automatically since you might have buttons bound to complex functions, for instance.

  • MwmDecorMenu โ€” should be assigned to title-bar buttons which display a menu. The default assignment is the leftmost button. When a window with the MwmFunctions Style option requests not to show this button, it is hidden. ๐Ÿ™ˆ
  • MwmDecorMin โ€” should be assigned to title-bar buttons which minimize or iconify the window. The default assignment is the second button over from the rightmost button. When a window with the MwmFunctions Style option requests not to show this button, it is hidden.
  • MwmDecorMax โ€” should be assigned to title-bar buttons which maximize the window. The default assignment is the rightmost button. When a window with the MwmFunctions Style option requests not to show this button, it is hidden. When the window is maximized, the vector pattern on the button looks pressed in.
  • MwmDecorShade โ€” should be assigned to title-bar buttons which shade the window (see WindowShade command). When the window is shaded, the vector pattern on the button looks pressed in.
  • MwmDecorStick โ€” should be assigned to title-bar buttons which make the window sticky. When the window is sticky, the vector pattern on the button looks pressed in.
  • MwmDecorLayer layer โ€” should be assigned to title-bar buttons which place the window in the layer numbered layer. When the window is on that specific layer, the vector pattern on the button looks pressed in.

ChangeDecor decor ๐Ÿ’œ

This command is deprecated and will be removed in the future. There are plans to replace it with a more flexible solution in fvwm-3.0.

Changes the decor of a window to decor. decor is "Default" or the name of a decor defined with AddToDecor. If decor is invalid, nothing occurs. If called from somewhere in a window or its border, then that window is affected. If called from the root window the user is allowed to select the target window. ChangeDecor only affects attributes which can be set using the AddToDecor command.

ChangeDecor CustomDecor1

DestroyDecor [recreate] decor ๐Ÿ’€

This command is deprecated and will be removed in the future. There are plans to replace it with a more flexible solution in fvwm-3.0.

Deletes the decor defined with AddToDecor, so that subsequent references to it are no longer valid. Windows using this decor revert to the "Default" decor. The optional parameter recreate tells fvwm not to throw away the decor completely but to throw away only its contents. If the decor is created again later, windows do not use it before the UseDecor style is applied again unless the decor was destroyed with the recreate option. The decor named "Default" cannot be destroyed. Periodt.

DestroyDecor CustomDecor1

TitleStyle [justification] [Height [num]] [MinHeight [num]] ๐ŸŒธ

Sets attributes for the title-bar. Justifications can be Centered, RightJustified or LeftJustified. Height sets the title bar's height to an amount in pixels. MinHeight sets the minimal height in pixels of the title bar. Defaults are Centered, the window's font height and no minimal height. To reset the font height to the default value, omit the num argument after the Height keyword. The MinHeight height is reset by Height or if given with no argument. Example:

TitleStyle LeftJustified Height 24

TitleStyle [state] [style] [-- [!]flag ...] ๐ŸŽ€

Sets the style for the title-bar. See also AddTitleStyle and ButtonStyle state can be one of "ActiveUp", "ActiveDown", "InactiveUp", or "InactiveDown". Shortcuts like "Active" and "Inactive" are allowed. The states with the "Toggled" prefix are allowed too, the title itself does not use "Toggled" states, but these states are used for the buttons with ButtonStyle UseTitleStyle. If state is omitted, then the style is added to every state. If parentheses are placed around the style and flags, then multiple state definitions can be given per line. style can be omitted so that flags can be set while not destroying the current style.

If a '!' is prefixed to any flag, its behavior is negated. Valid flags for each state include Raised, Flat and Sunk (these are mutually exclusive). The default is Raised. See the note in ButtonStyle regarding the "ActiveDown" state. Examples:

               TitleStyle ActiveUp HGradient 16 navy black
               TitleStyle \
               ActiveDown (Solid red -- flat) \
               Inactive (TiledPixmap wood.xpm)
               TitleStyle \
               ActiveUp (-- Flat) \
               ActiveDown (-- Raised) \
               InactiveUp (-- Flat) \
               InactiveDown (-- Sunk)

So that first one is giving โœจvarietyโœจ โ€” "ActiveUp" gets a horizontal gradient, "ActiveDown" goes solid red, and the "Inactive" states become a tiled wood pixmap. Then the second block makes "ActiveUp" and "InactiveUp" look flat, "ActiveDown" looks sunk (because the Raised flag on the "ActiveDown" state flips the relief and makes it appear sunk instead โ€” the drama of inversion ๐Ÿ’…), and "InactiveDown" ends up looking raised. And here's one that sets flags for every state, bestie:

TitleStyle -- flat

And for the full flattened vibe:

TitleStyle -- flat
ButtonStyle All Active (-- flat) Inactive (-- flat)

TitleStyle lowkey accepts every single ButtonStyle style and argument, no cap:

Simple, Default, Solid, Colorset, Vector, ?Gradient, Pixmap, AdjustedPixmap, ShrunkPixmap, StretchedPixmap, TiledPixmap, MiniIcon.

๐Ÿ‘‘ Head over to the ButtonStyle command for the full description of all of these styles and their arguments.


But wait โ€” there's more ๐Ÿ’–. On top of all those styles, TitleStyle also accepts a powerful MultiPixmap option. This lets you specify different pixmaps, colorsets or colors for different parts of the titlebar. Some of them get tiled or stretched to fit a particular space; others are discrete "transition" images. The definable sections are:

  • Main โ€” the full titlebar
  • LeftMain โ€” left of the title text
  • RightMain โ€” right of the title text
  • UnderText โ€” underneath the title text
  • LeftOfText โ€” just to the left of the title text
  • RightOfText โ€” just to the right of the title text
  • LeftEnd โ€” at the far left end of the titlebar (just after left buttons, if any)
  • RightEnd โ€” at the far right end of the titlebar (just before right buttons, if any)
  • Buttons โ€” under buttons, in the case of UseTitleStyle
  • LeftButtons โ€” under left buttons, in the case of UseTitleStyle
  • RightButtons โ€” under right buttons, in the case of UseTitleStyle

None of these are mandatory except for Main (or, if you don't define Main, you have to define both LeftMain and RightMain). And if no Buttons pixmaps are defined but UseTitleStyle is specified for one or more buttons, then Main, LeftMain or RightMain get used as appropriate. ๐Ÿซถ

The syntax for this style type is:

MultiPixmap section style arg, ...

...and you just keep going for whatever you want to define. The style can be either TiledPixmap, AdjustedPixmap, Colorset or Solid. See the ButtonStyle command for the description of these styles. For a transition section โ€” that's LeftEnd, LeftOfText, RightOfText or RightEnd โ€” AdjustedPixmap only resizes the pixmap in the y direction. And for the Colorset and Solid styles, a width of half the title bar height is assumed for the transition sections. ๐ŸŽ€

An example, bestie:

MultiPixmap Main AdjustedPixmap foo.xpm, \
      UnderText TiledPixmap bar.xpm, \
      Buttons Colorset 2

Also note that the old syntax is still supported: if you leave the style out, TiledPixmap is assumed, and sticking (stretched) between the section and the file name implies AdjustedPixmap. ๐Ÿฆ‹


  • UpdateDecor [decor] โ€” okay so, this command is deprecated and is getting removed in the future. There are plans to replace it with something more flexible in fvwm-3.0. โš ๏ธ

It's kept mainly for backward compatibility. And since every element of a decor gets updated immediately when it's changed, this command is mostly useless anyway. ๐Ÿ˜ญ

It updates window decorations. decor is an optional argument that specifies which decor to update. If you give it, then only windows assigned to that particular decor get updated. This command is useful, for instance, after a ButtonStyle, TitleStyle or BorderStyle (possibly used together with AddToDecor). And specifying an invalid decor results in all windows being updated. ๐Ÿ’€

โœจ Controlling the Virtual Desktop โœจ

  • DesktopName desk name โ€” defines the name of desktop number desk to name. ๐ŸŒธ This name is used in the WindowList command and in the FvwmPager, where it overrides the Label configuration option. And bonus: if consecutive names starting from desktop 0 are defined, then these names can be used by any EWMH compliant application (like a pager). iykyk ๐Ÿ’…
  • DesktopConfiguration global | per-monitor | shared โ€” this command controls how desktops should be managed by FVWM. ๐ŸŒˆ

By default, for all screens detected by FVWM through RandR support, the option of global means that all windows on the same desk across monitors are treated as one โ€” hence, when a change of desktop/page happens, the same change happens across all monitors.

With per-monitor, each RandR monitor has a separate copy of desktops, so they function independently of one another when switching desks/pages. ๐Ÿฆ‹

When shared is set, the desktops are shared amongst all monitors. So for example, with the following number of desktops defined with two monitors ([] is monitor1, and <> is monitor2):

    [0]     1      2      <3>     4

Moving between desktops would still honor the monitor the desktop is being requested on. If monitor1 wanted to switch to desktop 3, then that desktop is exchanged with monitor2, such that the following showed the active desktop on both monitors:

    <0>     1      2      [3]     4

This concept is similar to how spectrwm or xmonad handles desktops. ๐Ÿ‘‘

Note: each DesktopConfiguration mode can be changed on-the-fly. ๐Ÿ”ฅ
  • DesktopSize Horizontalx*Vertical* โ€” defines the virtual desktop size in units of the physical screen size. ๐ŸŽ€
  • EdgeResistance delay, EdgeResistance scrolling moving [screen-scrolling] โ€” tells how hard it should be to change the desktop viewport by moving the mouse over the edge of the screen. ๐Ÿ–ฑ๏ธ The parameter tells how many milliseconds the pointer must spend on the screen edge before fvwm moves the viewport. This is intended for people who use
EdgeScroll 100 100

but find themselves accidentally flipping pages when they do not want to. ๐Ÿ™ˆ If -1 is given as the delay, scrolling is disabled completely.

The second form of invocation with two or three arguments is obsolete and should be replaced with the following three commands as needed:

EdgeResistance scrolling
Style * EdgeMoveDelay scrolling
Style * EdgeMoveResistance moving
or
Style * EdgeMoveResistance moving screen-scrolling

Fvwm does this substitution automatically and prints a warning. โš ๏ธ

  • EdgeScroll [screen RANDRNAME] horizontal[p] vertical[p] [wrap | wrapx | wrapy] โ€” specifies the percentage of a page to scroll when the cursor hits the edge of a page. The optional screen RANDRNAME specifies the RandR monitor which this setting should apply to, ignoring all other monitors. Without this option, it applies the value to all monitors. A trailing p changes the interpretation to mean pixels. ๐Ÿ“

If you don't want any paging or scrolling when you hit the edge of a page, include

EdgeScroll 0 0

in your config file, or possibly better, set the EdgeThickness to zero. See the EdgeThickness command. If you want whole pages, use

EdgeScroll 100 100

Both horizontal and vertical should be positive numbers. ๐Ÿ’–

If the horizontal and vertical percentages are multiplied by 1000, or one of the keywords wrap, wrapx and wrapy is given, then scrolling wraps around at the edge of the desktop. If

EdgeScroll 100000 100000

is used, fvwm scrolls by whole pages, wrapping around at the edge of the desktop. ๐ŸŒ€

  • EdgeThickness [screen RANDRNAME] 0 | 1 | 2 โ€” this is the width or height of the invisible window that fvwm creates on the edges of the screen that are used for the edge scrolling feature.

The optional screen RANDRNAME specifies the RandR monitor which this setting should apply to, ignoring all other monitors. Without this option, it applies the value to all monitors. ๐ŸŒˆ

In order to enable page scrolling via the mouse, four windows called the "pan frames" are placed at the very edge of the screen. This is how fvwm detects the mouse's presence at the window edge. Because of the way this works, they need to be at the top of the stack and eat mouse events, so if you have any kind of error along the lines of: "mouse clicks at the edge of the screen do the wrong thing" you're having trouble with the pan frames and (assuming you do not use the mouse to flip between pages) should set the EdgeThickness to 0. ๐Ÿ˜ญ

A value of 0 completely disables mouse edge scrolling, even while dragging a window. 1 gives the smallest pan frames, which seem to work best except on some servers. ๐Ÿงš

2 is the default.

Pan frames of 1 or 2 pixels can sometimes be confusing โ€” for example, if you drag a window over the edge of the screen, so that it straddles a pan frame, clicks on the window near the edge of the screen are treated as clicks on the root window. ๐Ÿ’€

  • EwmhBaseStruts screen RANDRNAME left right top bottom โ€” where left, right, top and bottom are positive or null integers which define bands at the edge of the screen. If screen is given, followed by the RANDRNAME of a given display, then the EwmhBaseStruts are defined for just RANDRNAME. left defines a band on the left of your screen of width left, right defines a band on the right of your screen of width right, top defines a band on the top of your screen of height top and bottom defines a band on the bottom of your screen of height bottom. ๐Ÿ“ The unit is the pixel and the default is 0 0 0 0. These areas define additional reserved space to the reserved space defined by some ewmh compliant applications. This is used to compute the Working Area. See the Extended Window Manager Hints section for a definition of the Working Area. ๐Ÿ‘‘

EwmhNumberOfDesktops num [max]

okay so this one is niche-core โ€” it's only useful for an ewmh compliant pager or taskbar (think kpager or kicker taskbar) and not for fvwm modules (FvwmPager or FvwmIconMan). It makes a compliant application consider at least num desktops (desktop 0 all the way to desktop num-1). The optional max argument tells a compliant app to never consider more than max desktops. If max is 0 โ€” which is the default โ€” there is no limitation at all. ๐Ÿ’…

The actual number of desktops is determined dynamically. It's at least num, but it can be d if there's a window on desktop d-1 (or if the current desktop is desktop d-1) and d is less than or equal to max or max is null. Also, a compliant pager can ask to change num itself, and fvwm only accepts that if the number is less than or equal to max or if max is null.

heads up bestie: negative desktops are not supported by the ewmh specification.

The default is 4 0.


GotoDesk [screen RANDRNAME] [prev | arg1 [arg2] [min max]]

Switches the current viewport to another desktop (a.k.a. workspace, a.k.a. room ๐Ÿ ). The current monitor is used in per-monitor and shared DesktopConfiguration, unless the literal screen followed by a valid RandR monitor name is included.

The command takes 1, 2, 3, or 4 arguments:

  • 1 argument โ€” interpreted as a relative desk number.
  • 2 arguments โ€” understood as a relative and an absolute desk number.
  • 3 arguments โ€” a relative desk plus the minimum and maximum of the allowable range.
  • 4 arguments โ€” the relative, absolute, minimum and maximum values.

If a literal prev is given as the single argument, the last visited desk number is used. ๐Ÿ•ฐ๏ธ

If arg1 is non zero then the next desktop number is the current desktop number plus arg1.

If arg1 is zero then the new desktop number is arg2. (And if arg2 isn't present, then the command literally does nothing. ๐Ÿ™ˆ)

If min and max are given, the new desktop number is no smaller than min and no bigger than max. Values out of this range get truncated (if you gave an absolute desk number) or wrapped around (if you gave a relative desk number).

The syntax is the same as for MoveToDesk, which moves a window to a different desktop.

The number of active desktops is determined dynamically โ€” only desktops which contain windows or are currently being displayed count as active. Desktop numbers must be between 0 and 2147483647 (is that enough? ๐Ÿ˜ญ). Negative desktop numbers are not supported by the EWMH specifications and are no longer supported in fvwm.


GotoDeskAndPage screen | prev | desk xpage ypage

Switches the current viewport to another desktop and page, kinda like GotoDesk and GotoPage had a baby. The new desk is desk and the new page is (xpage,ypage). ๐Ÿฆ‹


GotoPage screen | prev | [options] x[p] y[p]

Moves the desktop viewport to page (x,y). The upper left page is (0,0), the upper right is (M,0), where M is one less than the current number of horizontal pages specified in the DesktopSize command. The lower left page is (0,N), and the lower right page is (M,N), where N is the desktop's vertical size as specified in the DesktopSize command.

To switch to a page relative to the current one, add a trailing 'p' after any or both numerical arguments. โœจ

Possible options:

  • wrapx โ€” wrap around the x coordinate when the viewport is moved beyond the border of the desktop.
  • wrapy โ€” wrap around the y coordinate when the viewport is moved beyond the border of the desktop.

The name of the RandR screen.

To go to the last visited page use prev as the first argument.

not me doing this in a pop-up menu ๐Ÿ™… โ€” the GotoPage function should not be used in a pop-up menu.

Examples:

# Go to page (2,3)
GotoPage 2 3

# Go to lowest and rightmost page
GotoPage -1 -1

# Go to last page visited
GotoPage prev

# Go two pages to the right and one page up
GotoPage +2p -1p

Scroll [screen RANDRNAME] [horizonal[p] vertical[p] | reverse]

Scrolls the virtual desktop's viewport by horizontal pages in the x-direction and vertical pages in the y-direction โ€” or starts interactive scrolling of the viewport. Either or both entries may be negative. Both horizontal and vertical values are expressed in percent of pages, so:

Scroll 100 100

means to scroll down and right by one full page. And:

Scroll 50 25

means to scroll right half a page and down a quarter of a page. ๐ŸŒธ

the tea: the Scroll function should not be called from pop-up menus. And normally, scrolling stops at the edge of the desktop.

If the horizontal and vertical percentages are 100 or more and are multiplied by 1000 then scrolling wraps around at the edge of the desktop. So if:

Scroll 100000 0

is executed over and over, fvwm moves to the next desktop page on each execution and wraps around at the edge of the desktop, so that every page gets hit in turn. ๐Ÿ‘‘

If the letter 'p' is appended to each coordinate (horizontal and/or vertical), then the scroll amount is measured in pixels.

Without arguments โ€” or if the option reverse is given โ€” interactive scrolling takes place. The viewport scrolls as the mouse is moved. With the reverse option, scrolling is done in the opposite direction of the mouse movement; without it, scrolling goes in the same direction as the mouse.

This binding:

Mouse 1 A CM Scroll reverse

gives an effect of grabbing and dragging the viewport with button 1 if Control and Meta is pressed. ๐Ÿ–ฑ๏ธ

If screen is given, followed by the RANDRNAME of a given display, then the specified screen is scrolled. This is only useful if using per-monitor or shared DesktopConfiguration and wanting to scroll a monitor other than the current monitor. Interactive scrolling always scrolls the current monitor.


๐Ÿฆ‹ User Functions and Shell Commands ๐Ÿฆ‹

AddToFunc [name [I | J | M | C | H | D action]]

Begins or adds to a function definition. Here's the vibe:

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

The function name is "Move-or-Raise", and it could be invoked from a menu or a mouse binding or key binding:

Mouse 1 TS A Move-or-Raise

The name must not contain embedded whitespace. No guarantees are made whether function names with embedded whitespace work or not, and this behavior may also change in the future without further notice. ๐Ÿ˜ฌ

The letter before the action tells what kind of action triggers the command which follows it:

  • I โ€” stands for "Immediate", and is executed as soon as the function is invoked.
  • J โ€” similar to "Immediate" but is delayed until a button is pressed or released or the pointer is moved, or the function completes. It is always executed before the other function actions.
  • M โ€” stands for "Motion", i.e. if the user starts moving the mouse.
  • C โ€” stands for "Click", i.e. if the user presses and releases the mouse button.
  • H โ€” stands for "Hold", i.e. if the user presses a mouse button and holds it down for more than ClickTime milliseconds.
  • D โ€” stands for "Double-click".

The action 'I' causes an action to be performed on the button-press, if the function is invoked with prior knowledge of which window to act on.

There is a number of predefined symbols that get replaced by certain values if they appear on the command line. Please refer to the Command Expansion section for details. โœจ

warning bestie: please read the comments on executing complex functions in the section Scripting and Complex Functions.

Examples:

If you call:

Key F10 R A Function MailFunction xmh "-font fixed"

and "MailFunction" is:

AddToFunc MailFunction
 + I Next ($0) Iconify off
 + I Next (AcceptsFocus, $0) Focus
 + I None ($0) Exec exec $0 $1

Then the last line of the function becomes:

 + I None (xmh) Exec exec xmh -font fixed

The expansion is performed as the function is executed, so you can use the same function with all sorts of different arguments. You could use:

Key F11 R A Function MailFunction zmail "-bg pink"

in the same config, if you wanted. An example of using "$[w.id]" is:

AddToFunc PrintFunction
 + I Raise
 + I Exec xdpr -id $[w.id]

Note that "$$" is expanded to '$'.

Another example: bind right mouse button within the window button number 6 (this is a minimize button for the win95 theme) to iconify all windows of the same resource:

AddToFunc FuncIconifySameResource "I" All ($0) Iconify on
Mouse 3 6 A FuncIconifySameResource $[w.resource]

Beep

As might be expected, this makes the terminal beep. ๐Ÿ””


DestroyFunc function

Deletes a function, so that subsequent references to it are no longer valid. You can use this to change the contents of a function during a fvwm session. The function can be rebuilt using AddToFunc. ๐Ÿ’€

DestroyFunc PrintFunction

Echo string

Prints a message to the debug log file, which requires logging to be enabled. See the -v option or PrintInfo for more information on both enabling debug logging and the log file location. Potentially useful for debugging things in your config or getting the value of variables. ๐Ÿ“

Echo Beginning style definitions...
Echo Current desk $[desk.n].

EchoFuncDefinition function

The EchoFuncDefinition is similar to the Echo command but prints the definition for the given function to the debug log file. It is useful to find out how fvwm handles quoting and for debugging functions. ๐Ÿงš


Exec command

Executes command. You should not use an ampersand '&' at the end of the command. You probably want to use an additional "exec" at the beginning of command. Without that, the shell that fvwm invokes to run your command stays until the command exits. In effect, you'll have twice as many processes running as you need. Note that some shells are smart enough to avoid this, but it never hurts to include the "exec" anyway. ๐Ÿ’…

The following example binds function key

in the root window, with no modifiers, to the exec function. The program rxvt is started with an assortment of options.

Key F1 R N Exec exec rxvt -fg yellow -bg blue \
-e /bin/tcsh

Note that this function doesn't wait for command to complete, so things like:

Exec "echo AddToMenu ... > /tmp/file"
Read /tmp/file

do not work reliably (see the PipeRead command). ๐Ÿ˜ญ

ExecUseShell [shell] ๐Ÿš

okay so this one makes Exec use the shell you tell it to, or โ€” if you don't give it a shell โ€” whatever's chillin' in your $SHELL environment variable. And if that's not a thing either? It falls back to the default Bourne shell (/bin/sh). bestie, your shell your rules ๐Ÿ’…

ExecUseShell
ExecUseShell /usr/local/bin/tcsh

Function FunctionName ๐ŸŽ€

This is how you bind a function you already defined to a key or a mouse button. Like, the function has to exist first โ€” this just hooks it up.

The example below binds mouse button 1 to a function called "Move-or-Raise", whose definition was given as an example earlier in this man page. Once you do this binding, fvwm runs the "move-or-raise" function every single time button 1 gets pressed in a window's title-bar. slay โœจ

Mouse 1 T A Function Move-or-Raise

You can also just... drop the keyword Function, as long as FunctionName doesn't happen to collide with an actual fvwm command. (iykyk โ€” naming is everything.)

โš ๏ธ Warning: Please read the comments on executing complex functions in the section Scripting and Complex Functions. Do not skip this, bestie, it matters ๐Ÿ˜ญ

InfoStoreAdd key value ๐Ÿ’พ

Stores a value at the given key. Super handy for stashing generic info you want to keep around for the whole lifetime of an fvwm config file โ€” think, like, storing program preferences for opening video files.

The whole point of this command is to keep internal information inside fvwm where fvwm functions can use it, or where it can be used when opening programs of a certain type. Before this existed, the only way to do it was via SetEnv, and honestly? discouraged. Because that shoves the info into the environment, which pollutes it and makes the info global to other processes started by fvwm โ€” which might then go ahead and modify them, and that is very much not what you wanted ๐Ÿ™ˆ

So the vibe of InfoStoreAdd is: still let you store that info, just keep it internal to fvwm. no leakage, no drama. periodt.

You can build up as many key/value pairs as you want, no cap. Getting the value back out happens through fvwm's usual expansion mechanism โ€” see the Command Expansion section for the deets. Like:

InfoStoreAdd teddybearprog xteddy

# Echo the value of teddybearprog
Echo $[infostore.teddybearprog]

Removing an entry from the InfoStore is a job for the InfoStoreRemove command. ๐Ÿ‘‘


InfoStoreRemove key ๐Ÿ—‘๏ธ

Removes an entry at the given key from the InfoStore. Simple as. Example:

InfoStoreRemove teddybearprog

Nop ๐Ÿซฅ

Does absolutely nothing. Literally nothing. And that's its power, bestie ๐Ÿ’… It's used to insert a blank line or a separator in a menu.

If the menu item specification looks like:

AddToMenu MyMenu " " Nop

then a blank line gets inserted. And if it looks like:

+ "" Nop

then you get a separator line instead. Main character energy from a command that does zero things.

It can also be used as the double-click action for Menu or Popup. ๐ŸŒˆ


PipeRead command [quiet] ๐ŸŽก

Makes fvwm read commands from the output of command. That command is executed by /bin/sh exactly as if you typed it on the command line. If the command is more than one word long it must be quoted, no exceptions. So useful for building dynamic menu entries based on a directory's contents, for example.

If the keyword Quiet follows the command, then no message is produced if the command isn't found. ๐Ÿคซ

Example:

AddToMenu HomeDirMenu
PipeRead 'for i in $HOME/*; \
do echo "+ $i Exec xterm -e vi $i"; done'
๐Ÿ“ Note: By default, PipeRead changes the pointer to a watch cursor while it's running. But some commands โ€” xwd, for instance โ€” need to take control of the pointer themselves and just won't work with that going on. To disable the watch cursor, run this command before the PipeRead:
BusyCursor Read off

PipeRead executes synchronously. So if you wanna Exec something but need the command to run synchronously, you might do something like:

PipeRead 'command 1>&2'

That redirection sends any output from the program off to stderr instead of letting fvwm read it as a sequence of commands.

PipeRead returns 1 if the given command could be executed, or -1 if not. (See the section Conditional Commands for what those return codes actually mean.) ๐Ÿ”ฅ


Read filename [quiet] ๐Ÿ“–

Makes fvwm read commands from the file named filename. If the keyword Quiet follows the command, no message is produced when the file isn't found.

If filename doesn't start with a slash (/), fvwm goes looking in the user's data directory first, then the system data directory. The user's data directory is $HOME/.fvwm by default, and you can override it by exporting FVWM_USERDIR set to any other directory you like.

Read returns 1 if the file could be read, or -1 if not. (Again โ€” see Conditional Commands for the return code tea โ˜•)


SetEnv variable value ๐ŸŒ

Sets an environment variable to a new value, just like the shell's export or setenv command. The variable and its value get inherited by processes started directly by fvwm. For example:

SetEnv height HEIGHT

Silent command ๐Ÿค

okay so a bunch of commands need a window to operate on. And if no window was selected when such a function gets invoked, the user gets asked to select one. Sometimes that behavior is just... not it โ€” like when the function was called by a module and the window that was selected at first doesn't even exist anymore ๐Ÿ˜ญ

You can prevent that by putting Silent in front of the fvwm command. If a function that needs a window gets called with Silent and there's no window selected, it simply returns without doing anything. And if Silent is used on a user defined function, it affects all function and sub function calls until the original function exits.

Another usage of Silent is with the binding commands Key, PointerKey and Mouse โ€” there it disables error messages.

Silent also disables the error message for non-existent commands.

๐Ÿ“ Note: This command is treated as a prefix to its command. Expansion of the command line is done as if Silent was not there. (Yes, that's a little cursed. It's fine. ๐Ÿซ )

Examples:

Silent Move 0 0
Silent User_defined_function
# do not complain on keyboards without "Help" key
Silent Key Help R A Popup HelpMenu

UnsetEnv [variable] ๐Ÿซง

Unsets an environment variable, just like the shell's export or unsetenv command. The variable then gets removed from the environment array that's inherited by processes started directly by fvwm. gone, deleted, no trace ๐Ÿ’œ


Wait window โณ

This command is meant to be used in fvwm functions only. It pauses the execution of a function until a new window matching window shows up.

window can be a window's name, class, or resource string. And it may contain the wildcards * and ?, which get matched in the usual Unix filename manner. This is especially useful in the "InitFunction" when you're trying to start windows on specific desktops:

AddToFunc InitFunction
 + I Exec exec xterm -geometry 80x64+0+0
 + I Wait xterm
 + I GotoDesk 0 2
 + I Exec exec xmh -font fixed -geometry \
 507x750+0+0
 + I Wait xmh
 + I GotoDesk 0 0

So what that function is doing: it starts an xterm on the current desk, waits for it to map itself, then switches to desk 2 and starts an xmh. Once the xmh window appears, control moves to desk 0. chef's kiss sequence ๐Ÿ”ฅ

Fvwm stays partially functional during a wait, but any input from the modules gets queued up and only processed after the window appears โ€” or after the command is aborted. So, for example, you can't focus windows with FvwmIconMan or FvwmPager during a wait. Just so you know. ๐Ÿ‘€

You can escape from a Wait pause by pressing Ctrl-Alt-Escape (where Alt is the first modifier). To redefine that key sequence, see the EscapeFunc command.


Status On | Off ๐Ÿ“ก

Turns status either On or Off. This sends information in JSON format down a named pipe (which you set via the FVWM_STATUS_PIPE env var) about the current desks, number of windows, and so on.

The whole point is to give third-party tools a fast way to find out what's happening in Fvwm. Like, the JSON could get manipulated and piped to tools such as lemonbar, polybar, etc. โœจ

The format of the JSON blob looks like this:

{
    "version": 3,
    "current_screen": "HDMI2",
    "screens": {
        "HDMI2": {
            "randr_order": 0,
            "current_client": "n6tadam@shuttle: ~",
            "desktops": {
                "0": {
                    "number": 0,
                    "is_urgent": false,
                    "is_current": true,
                    "number_of_clients": 5
                },
            },
        },
     },
}

These sections repeat for all screens/groups/etc โ€” depending on how many there are of each. ๐Ÿ’–


Conditional Commands ๐ŸŒˆ

Conditional commands are commands that only get executed if certain conditions are met. Most conditional commands work on windows โ€” like Next, ThisWindow or All. There's exactly one conditional command, Test, that works on global conditions unrelated to windows. The syntax of the conditions is described below. And for readability, the list of conditions lives at the end of this section. ๐Ÿ“š


Return Codes ๐Ÿ”ข

All commands in this section (unless specifically stated otherwise for that command) also have a return code that can be:

  • 1 โ€” if the condition was met โœ…
  • 0 โ€” if the condition was not met โŒ

Some commands may return -1, which means an error occurred and the return code is useless. And the Break command returns -2.

On top of that, the return codes of commands run inside complex functions get passed to the invoking complex function. The return code is what the TestRc command uses โ€” so go check the commands' descriptions for examples. You can also access the return code through the variable $[cond.rc].

Non conditional commands do not modify the return code of the last conditional command.

๐Ÿšจ Important note: return codes are only defined inside functions created with the AddToFunc command, and they are not inherited by sub functions. If you want to run a command without altering the return code, the KeepRc command is your girl. ๐Ÿ’…

The Ring of Windows ๐Ÿ’

Fvwm stores windows in a ring internally. Think of the focused window as a cursor sitting on the current position in that ring. The Next command and many other commands search forwards through the ring for a matching window, and Prev searches backwards. ๐Ÿ”„

The windows in the ring are either ordered by creation time (that's the case if the !FPSortWindowlistByFocus, NeverFocus or MouseFocus styles are used) or by the last time they had the focus. ๐Ÿฆ‹


List of Conditional Commands ๐Ÿ“‹

๐Ÿ’– All [options] [(conditions)] command

Run command on every window that meets the conditions, bestie. It returns 1 if any window matched the condition and 0 if none did. The execution starts at the top of the window ring and walks down toward the bottom. The options can be any combo of Reverse and UseStack. Give it Reverse and the execution order flips around. Give it UseStack and All walks the stacking order instead of the window ring. Peep the Conditions section for the full list of conditions.

This command implies the conditions CirculateHit, CirculateHitIcon and CirculateHitShaded. You can turn them off by specifying !CirculateHit etc. explicitly. ๐Ÿ’…

๐ŸŒธ Any [(conditions)] command

Performs command if any window satisfying all the conditions exists. The command runs in the context of the root window. Conditions list? Conditions section, go look. โœจ


๐ŸŽ€ Break [levels]

If Break shows up inside a function, function execution is terminated immediately โ€” the rest of the function's commands just don't happen, periodt. Normally, all nested invocations of complex functions are left. But you can hand it an optional integer levels to break out of that many nested functions and keep going on a higher level function instead. The Break command always has the return code -2. Example:

AddToFunc PickWindowRaiseAndDeiconify
+ I Pick
+ I TestRc (Error) Break
+ I Raise
+ I Iconify off

๐Ÿฆ‹ Current [(conditions)] command

Performs command on the currently focused window โ€” but only if it satisfies all the conditions. See the Conditions section for a list of conditions. ๐Ÿ‘‘

This command implies the conditions CirculateHit, CirculateHitIcon and CirculateHitShaded. They can be turned off by specifying !CirculateHit etc. explicitly.

๐ŸŒˆ Direction [FromPointer] direction [(conditions)] command

Performs command (typically Focus) on a window in the given direction that satisfies all the conditions. Normally the center of the currently focused window โ€” or the context window the command was invoked in โ€” is the starting point. But if there's no such window, or if you pass the FromPointer option, the current position of the pointer is the starting point instead. ๐Ÿซถ

The direction can be one of "North", "Northeast", "East", "Southeast", "South", "Southwest", "West", "Northwest" and "Center". Which window Direction picks depends on the angle and distance between the center points of the windows โ€” closer windows are a better match than the far-away ones, no cap. The Center direction just grabs the window closest to the starting point. Returns -1 if you fed it an invalid direction. See the Conditions section for a list of conditions.


๐Ÿ’œ KeepRc command

Runs the command but does not alter the return code of the previous command. Note: KeepRc is treated as a prefix to its command, and expansion of the command line is done as if KeepRc was never there. ๐Ÿงš


โญ Next [(conditions)] command

Performs command (typically Focus) on the next window satisfying all the conditions. If the command is running in a window context, it starts looking for a matching window from there. Otherwise it starts at the focused window. See the Conditions section for a list of conditions.


๐Ÿ“ None [(conditions)] command

Performs command if no window satisfying all the conditions exists. The command runs in the context of the root window. Returns 1 if no window matches the conditions and 0 otherwise. See the Conditions section for a list of conditions.

This command implies the conditions CirculateHit, CirculateHitIcon and CirculateHitShaded. They can be turned off by specifying !CirculateHit etc. explicitly.

๐Ÿ’€ NoWindow command

Performs command, but removes the window context if there is any. This isn't really a conditional command โ€” it's a prefix, and it's lowkey useful in menu items that should operate without a window even when that menu is bound to window decorations. ๐Ÿ™ˆ


โœจ Pick [(conditions)] command

Pick works like Function if it's invoked in the context of a window. If it's invoked in the root window, it first asks the user to pick a window and then executes the command in the context of that window. This avoids annoying multiple selections with complex functions. The command is executed only if the given conditions are met. Returns -1 if no window was selected. See the Conditions section for a list of conditions.

This command implies the conditions CirculateHit, CirculateHitIcon and CirculateHitShaded. They can be turned off by specifying !CirculateHit etc. explicitly.

๐ŸŒธ PointerWindow [(conditions)] command

Performs command if the window under the pointer satisfies all the conditions. Returns -1 if there is no window under the pointer. See the Conditions section for a list of conditions.

This command implies the conditions CirculateHit, CirculateHitIcon and CirculateHitShaded. They can be turned off by specifying !CirculateHit etc. explicitly.

๐Ÿฆ‹ Prev [(conditions)] command

Performs command (typically Focus) on the previous window which satisfies all the conditions. If the command is running in a window context, it starts looking for a matching window from there. Otherwise it starts at the focused window. See the Conditions section for a list of conditions.


๐Ÿ”ฅ ScanForWindow [FromPointer] dir1 dir2 [(conditions)] command

Performs command (typically Focus) on a window in the given direction that satisfies all the conditions. Normally, the center of the currently focused window โ€” or the context window the command was invoked in โ€” is the starting point. Lacking such a window, or when the FromPointer option is given, the current position of the pointer is the starting point.

The direction dir1 may be one of "North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West", and "NorthWest". Which window ScanForWindow selects depends first on the position along the primary axis given by dir1. If any windows have the exact same coordinate along the primary axis, the secondary direction is used to order the windows. The direction dir2 may be one of the same set of values as dir1. If dir2 is not perfectly perpendicular to dir1, ScanForWindow returns a failure. When using ScanForWindow repeatedly with the same arguments, it is guaranteed that all windows matching the conditions will eventually be found. If the focus reaches a limit along the primary axis, it wraps around to the opposite side. Returns -1 if an invalid direction was given. See the Conditions section for a list of conditions. ๐ŸŒˆ


๐Ÿ‘‘ Test [(test-conditions)] command

Performs command if all test-conditions are satisfied. The test-conditions are keywords with possible arguments from the list below, separated by commas or whitespace. They include:

  • Version operator x.y.z
  • EnvIsSet varname
  • EnvMatch varname pattern
  • StrMatch string pattern
  • EdgeHasPointer direction
  • EdgeIsActive direction
  • Start
  • Init
  • Restart
  • Exit
  • Quit
  • ToRestart
  • True
  • False
  • F
  • R
  • W
  • X
  • I

A test-condition prefixed with "!" is negated. ๐Ÿ’…

The Version operator x.y.z test-condition is fulfilled if the logical condition of the expression is true. Valid operator values are: >=, >, <=, <, == and !=.

Example:

Test (Version >= 2.5.11) Echo 2.5.11 or later.

The EnvIsSet varname test-condition is true if the given environment variable is set. The EnvMatch varname pattern test-condition is true if pattern matches the given environment or infostore variable value. (See InfoStoreAdd.) The pattern may contain special "*" and "?" chars. The "varname" is coded without the leading dollar sign ($). ๐Ÿ™ˆ

The StrMatch string pattern tests if the given string matches the given pattern, which is a case sensitive string that may contain special "*" and "?" characters for wild cards. This can be used in place of EnvMatch with different syntax, and it also allows testing if other variable expansions are equal to a certain value. For example, to test if the current monitor's name is "DP-2" use:

Test (StrMatch $[monitor.current] DP-2) Echo True

# StrMatch and EnvMatch have different syntaxes:
Test (EnvMatch HOME /home/username) ...
Test (StrMatch $[HOME] /home/username) ...

The EdgeHasPointer [direction] test-condition is true if the edge in the given direction currently contains the pointer. The EdgeIsActive [direction] test-condition is true if the edge in the given direction currently is active. An edge is active, and can contain a pointer, if either a command is bound to it or edge scroll is available in that direction. The direction may be one of Any, North, Top, Up, West, Left, South, Bottom, Down, Right and East. If no direction is specified, Any is assumed. โœจ

The Start test-condition is the same as either Init or Restart. It is only true on startup or restart prior and during StartFunction execution. The Exit test-condition is the same as either Quit or ToRestart. It is only valid on shutdown during ExitFunction function execution.

The True and False test-conditions are unconditionally true and false.

Additionally, if a test-condition name is not recognized, the Error return code is set and the command is not executed. ๐Ÿ˜ญ

The F file, R file, W file, X file and I file test-conditions test for existence of the given [F]ile (possibly with [R]ead/[W]rite permissions), e[X]ecutable (in $PATH), or the [I]mage (in ImagePath).

Example:

AddToFunc StartFunction I Test (Init) Exec exec xterm
AddToFunc VerifyVersion
+ I Test (Version 2.5.*) Echo 2.5.x detected
+ I TestRc (NoMatch) \
Test (!Version 2.6.*) Echo Future version
+ I TestRc (NoMatch) \
Echo 2.6.x is detected

Test (F $[FVWM_USERDIR]/local-config) Read local-config
Test (X xterm-utf16) Exec exec xterm-utf16

TestRc

TestRc [([!]returncode)] command

Okay bestie, this one is the "so what happened last time?" checker. It runs command only if the last conditional command handed back the value returncode. And instead of typing the boring numbers โ€” 0 (no match), 1 (match), -1 (error), and -2 (break) โ€” you can just use the cute symbolic names "NoMatch", "Match", "Error" and "Break". If you don't give a returncode at all, it assumes the default 0. Slap a '!' in front of the return code and it flips: the command runs when the return code does not match what the conditional command gave back.

๐Ÿšจ Real talk: TestRc can only be used inside functions. Nowhere else. If command is itself another conditional command, then the previous return code gets replaced by the new one. Periodt.

Example, because obviously:

AddToFunc ToggleXterm
+ I All (my_xtermwindow) Close
+ I TestRc (NoMatch) Exec xterm -T my_xtermwindow

ThisWindow

ThisWindow [(conditions)] command

ThisWindow runs the command you gave it in the context of the current operand window. If there's no operand window โ€” like, if it got invoked in the root window โ€” the command is just ignored, no drama. And heads up: ThisWindow is never interactive. It only fires if the conditions you gave are met. Returns -1 if you used it outside a window context. (Peep the Conditions section below for the full list of conditions. ๐Ÿ‘€)

This command implies the conditions CirculateHit, CirculateHitIcon and CirculateHitShaded. Want them off? Say "!CirculateHit" etc. explicitly. Your call.

WindowId

WindowId [id] [(conditions)] | [root] command

The WindowId command hunts down a specific window id and runs the command on it. The second form of the syntax grabs the window id of the root window instead. The window that id points to might belong to a window that isn't managed by fvwm โ€” and yeah, most commands can't operate on those, but there are some exceptions, like the WarpToWindow command, which absolutely can. Returns -1 if there's no window with that id. Check the Conditions section for the conditions list.

Same deal as before: this command implies CirculateHit, CirculateHitIcon and CirculateHitShaded, and you can turn them off by saying !CirculateHit etc. explicitly.

Examples, because we love a demo:

WindowId 0x34567890 Raise
WindowId root 1 WarpToWindow 50 50
WindowId $0 (Silly_Popup) Delete

Back in the day, this command was mostly useful for functions used with the WindowList command, or for selectively processing FvwmEvent calls (like in that last example). But currently these handler functions are called within a window context anyway, so honestly this command isn't really needed in those cases anymore. Still, it can come in clutch if, say, you wanna stash the window id in an environment variable for later. Iconic behaviour:

Pick SetEnv BOOKMARKED_WINDOW $[w.id]
WindowId $[BOOKMARKED_WINDOW] WarpToWindow

โœจ Conditions โœจ

The conditions you can pass as an argument to any conditional command are a list of keywords, separated by commas, all wrapped up in parentheses. Unless it says otherwise, conditional commands accept all the conditions listed below. Little history lesson: earlier versions of fvwm wanted the conditions separated by whitespace instead of commas, and enclosed in brackets instead of parentheses โ€” that's still supported for backward compatibility, so no stress if you see old configs.

On top of all that, the conditions can include one or more window names to match against. If you give more than one window name, then all of them have to match. The window name, icon name, class, and resource are all considered when fvwm is trying to find a match. Each name can use the wildcards '*' and '?', and can be made of two or more alternatives separated by the character '|', which acts as an OR operator. (Heads up: if you're using OR operators, they must not be separated by spaces from the names. Don't do that.) Each window name can start with '!', which blocks the command if any of the window name, icon name, class or resource match. But โ€” and this is important โ€” '!' must not be applied to individual names inside a group separated by OR operators. It goes at the beginning of the group only, and then it operates on the whole group. Okay? ๐Ÿ’…

Examples:

Next ("Netscape|konqueror|Mozilla*") WarpToWindow 99 90

That one goes to the next web browser window, no matter which of the three named web browsers is actually being used. Versatile queen. ๐Ÿ‘‘

Next ("Mozilla*", "Bookmark*") WarpToWindow 99 90

This one goes to Mozilla's bookmark manager window, ignoring other Mozilla windows and other browsers' bookmark windows. Very specific, very demure.

All ("XTerm|rxvt", !console) Iconify

This iconifies all the xterm and rxvt windows on the current page โ€” except the one named "console" (that's with the -name option to xterm), which gets excluded. Sorry console, not today.

Next (!"FvwmPager|FvwmForm*|FvwmButtons") Raise
Next (!FvwmPager, !FvwmForm*, !FvwmButtons) Raise

These two commands are equivalent; either one raises the next window that isn't one of the named fvwm modules. Pick whichever one your brain likes better.

Any condition can be negated by putting an exclamation mark ('!') directly in front of its name. That's it, that's the trick.

  • AcceptsFocus
  • AnyScreen
  • CirculateHit
  • CirculateHitIcon
  • CirculateHitShaded
  • Closable
  • CurrentDesk
  • CurrentGlobalPage
  • CurrentGlobalPageAnyDesk
  • CurrentPage
  • CurrentPageAnyDesk
  • CurrentScreen
  • Desk
  • FixedPosition
  • FixedSize
  • Focused
  • HasBorders
  • HasHandles
  • HasPointer
  • HasTitle
  • TitleAtTop
  • TitleAtBottom
  • TitleAtLeft
  • TitleAtRight
  • Iconic
  • Iconifiable
  • Layer [n]
  • Maximizable
  • Maximized
  • Overlapped
  • PlacedByButton n
  • PlacedByButton3
  • PlacedByFvwm
  • Raised
  • Shaded
  • State n
  • Sticky
  • StickyAcrossDesks
  • StickyAcrossPages
  • StickyIcon
  • StickyAcrossDesksIcon
  • StickyAcrossPagesIcon
  • Transient
  • Visible

Now let's break down what each of these little icons actually do. โœจ

The AcceptsFocus condition excludes all windows that don't want the input focus (the application set the "Input hints" for the window to False) and that don't use the Lenience option of the Style command. Also, all windows using the NeverFocus style get ignored. Quick note: !Lenience is equivalent to the deprecated option NoLenience. Deprecated! You heard me. ๐Ÿ™ˆ

With the AnyScreen condition used together with any of the Current... conditions, windows that don't intersect the screen containing the mouse pointer are considered for a match too. Like this:

# Focus next window on current page,
# regardless of screen
Next (CurrentPage, AnyScreen) Focus

The CirculateHit and CirculateHitIcon options override the CirculateSkip and CirculateSkipIcon Style attributes for normal or iconic windows. The CirculateHitShaded option overrides the CirculateSkipShaded Style. All three options are turned on by default for the Current command. You can turn them off by specifying !CirculateHit etc. explicitly.

โš ๏ธ Do not confuse these conditions with the style options of the same name. They are not the same thing, bestie. Specifically:
Style foo CirculateSkip
Next (foo, CirculateHit) ...

is not the same as

Style foo CirculateHit ...
Next (foo)

The first one selects windows with the name foo only in the Next command. In the second example, those windows are always matched in all conditional commands. Different vibes entirely.

The Closable condition matches only windows that are allowed to be closed.

The CurrentDesk condition matches only windows that are on the current desk.

The CurrentGlobalPage condition matches only windows that are on the current page of the current desk, regardless of which screen the window is on. This condition implicitly activates the CurrentDesk condition.

The CurrentGlobalPageAnyDesk condition matches only windows that are on the current page of any desk, regardless of RandR screen.

The CurrentPage condition matches only windows that are on the current page of the current desk. This condition implicitly activates the CurrentDesk condition.

The CurrentPageAnyDesk and CurrentScreen conditions matches only windows that are on the current page of any desk.

The Screen [name] condition matches only windows which are on the specified screen.

The Desk [n] condition matches only windows which are on the specified desk.

The FixedPosition condition excludes all windows that don't have a fixed position โ€” whether that was set through WM hints or the Style option FixedPosition. Example time:

DestroyFunc ToggleFixedGeometry
AddToFunc   ToggleFixedGeometry
+ I Pick (FixedPosition) \
WindowStyle VariablePosition, VariableSize
+ I TestRc (NoMatch) WindowStyle FixedPosition, FixedSize

The FixedSize condition excludes all windows that don't have a fixed size โ€” again, either set through WM hints or the Style option FixedSize.

The Focused matches on the window that currently has the keyboard focus. Not super useful for the Current command, but you can absolutely use it with the other conditional commands.

The HasBorders condition excludes all windows that don't have borders.

The HasHandles condition excludes all windows that don't have resize handles.

The HasPointer condition excludes all windows that don't contain the pointer.

The HasTitle condition excludes all windows that don't have a titlebar.

The TitleAtTop, TitleAtBottom, TitleAtLeft, TitleAtRight conditions test for the titlebar at that window location. (Yes, titlebars can go places. ๐Ÿฆ‹)

The Iconic condition matches only iconic windows.

The Iconifiable condition matches only windows that are allowed to be iconified.

The Layer [n] condition matches only windows on the specified layer. The optional argument of the Layer condition defaults to the layer of the focused window. The negation !Layer switches off the Layer condition.

The Maximizable condition matches only windows that are allowed to be maximized.

The Maximized condition matches only maximized windows.

  • Overlapped โ€” only matches windows that are overlapped by other windows on the same layer. (Or by unmanaged windows, but only if you turned on the RaiseOverUnmanaged option of the BugOpts command.) Heads up: this condition can be slow if you've got a lot of windows open, or if RaiseOverUnmanaged is on and your connection to the X server is being sluggish. ๐Ÿ’€
  • PlacedByButton n โ€” fulfilled when the last interactive motion of the window (either via the Move command or as ManualPlacement) got finished off by pressing mouse button n. Example time:
Mouse   1 T     A       Function MoveWindow

DestroyFunc MoveWindow
AddToFunc MoveWindow
+ C Move
+ C ThisWindow (PlacedByButton 5) WindowShade off
+ C TestRc (Match) Maximize on 0 100
+ C ThisWindow (PlacedByButton 4) WindowShade on
  • PlacedByButton3 โ€” same meaning as PlacedByButton 3. It's literally just hanging around for backward compatibility, bestie. ๐Ÿซถ
  • PlacedByFvwm โ€” excludes every window that was placed manually or by using the user or program position hint. Not it, bye. ๐Ÿ™ˆ
  • Raised โ€” only matches windows that are fully visible on the current viewport and not overlapped by any other window. Main character energy only. ๐Ÿ‘‘
  • Shaded โ€” only matches shaded windows (peep the WindowShade command for the tea).
  • State n or !State n โ€” only matches windows with the specified integer state set (or unset). See the State command for the details. The argument can range from 0 to 31. โœจ
  • Sticky, StickyAcrossDesks and StickyAcrossPages โ€” only match windows that are currently sticky, sticky across all desks, or sticky across all pages. Go read the Style options with the same names, plus the Stick, StickAcrossDesks and StickAcrossPages commands for the full story.
  • StickyIcon, StickyAcrossDesksIcon and StickyAcrossPagesIcon โ€” only match windows that become sticky, sticky across all desks, or sticky across all pages when they're in iconified state. The little icon glow-up. ๐ŸŽ€
  • Transient โ€” only matches windows that have the "transient" property set by the application. That's usually the case for application popup menus and dialogs. You can use the FvwmIdent module to find out whether a specific window is transient. Detective work fr fr. ๐Ÿ”
  • Visible โ€” only matches windows that are at least partially visible on the current viewport and not completely overlapped by other windows.

Module Commands ๐Ÿ’…

Fvwm keeps a whole database of module configuration lines, and they look like this:

*<ModuleName>: <Config-Resource>

where <ModuleName> is either a real module name or an alias.

That database gets initially filled from the config file (or from the output of the -cmd config command), and you can modify it later โ€” either by a user (via FvwmCommand) or by modules themselves. Cute, right? โœจ

When modules run, they read the appropriate portion of the database. (The whole concept is similar to the one used in the X resource database.)

The commands for manipulating the module configuration database are described below, bestie.

* module_config_line

Defines a module configuration. module_config_line consists of a module name (or a module alias) and a module resource line. The new syntax allows a delimiter, a colon and optional spaces between the module name and the rest of the line โ€” this is recommended to avoid conflicts. ๐ŸŒธ

*FvwmPager: WindowBorderWidth 1
*FvwmButtons-TopRight: Geometry 100x100-0+0
*FvwmButtons-Bottom: Geometry +0-0

DestroyModuleConfig module_config

Deletes module configuration entries, so that new configuration lines can be entered instead. This is also sometimes the only way to turn back some module settings that were previously defined. It changes the way a module runs during a fvwm session without restarting. Wildcards can be used for portions of the name as well.

The new non-conflicting syntax allows a delimiter, a colon and optional spaces between the module name and the rest of the line. In this case a module name (or alias) can't have wildcards. ๐Ÿ’…

DestroyModuleConfig FvwmButtons*
DestroyModuleConfig FvwmForm: Fore
DestroyModuleConfig FvwmIconMan: Tips*

KillModule modulename [modulealias]

Causes the module which was invoked with name modulename to be killed. The name may include wildcards. If modulealias is given, only modules started with the given alias are killed.

# kill all pagers
KillModule FvwmPager

Module FvwmEvent SoundEvent
KillModule FvwmEvent SoundEvent

Module modulename [moduleparams]

Specifies a module with its optional parameters which should be spawned. Currently several modules, including FvwmButtons, FvwmEvent, FvwmForm, FvwmPager, FvwmScript support aliases. Aliases are useful if more than one instance of the module should be spawned. Aliases may be configured separately using the * syntax. To start a module FvwmForm using an alias MyForm, the following syntax may be used:

Module FvwmForm MyForm

At the current time the available modules (included with fvwm) are FvwmAnimate (produces animation effects when a window is iconified or de-iconified), FvwmAuto (an auto raise module), FvwmBacker (to change the background when you change desktops), FvwmBanner (to display a spiffy XBM, XPM, PNG or SVG), FvwmButtons (brings up a customizable tool bar), FvwmPrompt (to execute fvwm commands directly), FvwmEvent (trigger various actions by events), FvwmForm (to bring up dialogs), FvwmIconMan (a flexible icon manager), FvwmIdent (to get window info), FvwmPager (a mini version of the desktop), FvwmPerl (a Perl manipulator and preprocessor), FvwmProxy (to locate and control obscured windows by using small proxy windows), FvwmRearrange (to rearrange windows), FvwmScript (another powerful dialog toolkit). These modules have their own man pages. There may be other modules out on there as well. ๐Ÿฆ‹

Modules can be short lived transient programs or, like FvwmButtons , can remain for the duration of the X session. Modules are terminated by the window manager prior to restarts and quits, if possible. See the introductory section on modules. The keyword Module may be omitted if modulename is distinct from all fvwm commands.

ModuleListenOnly modulename [moduleparams]

This command works like the Module command, but fvwm never sends any messages to the module. This may be handy to write a module as a shell script that is triggered by external events, without the burden of having to answer packets sent by fvwm. For example, a module written as a shell script may change labels of the FvwmButtons module to implement a simple clock. โฐ

ModulePath path

Specifies a colon separated list of directories in which to search for modules. To find a module, fvwm searches each directory in turn and uses the first file found. Directory names on the list do not need trailing slashes.

The ModulePath may contain environment variables such as $HOME (or ${HOME}). Further, a + in the path is expanded to the previous value of the path, which lets you easily append or prepend to the path. Obsessed with that, honestly. ๐Ÿซถ

For example:

ModulePath ${HOME}/lib/fvwm/modules:+

The directory containing the standard modules is available via the environment variable $FVWM_MODULEDIR.

ModuleSynchronous [Expect string] [Timeout secs] modulename

The ModuleSynchronous command is very similar to Module. Fvwm stops processing any commands and user input until the module sends a string beginning with "NOP FINISHED STARTUP" back to fvwm. If the optional Timeout is given fvwm gives up if the module sent no input back to fvwm for secs seconds. If the Expect option is given, fvwm waits for the given string instead. ModuleSynchronous should only be used during fvwm startup to enforce the order in which modules are started. This command is intended for use with the (currently hypothetical) module that should be in place before other modules are started.

Warning: it is quite easy to hang fvwm with this command, even if a timeout is given. Be extra careful choosing the string to wait for. Although all modules in the fvwm distribution send back the "NOP FINISHED STARTUP" string once they have properly started up, this may not be the case for third party modules. Moreover, you can try to escape from a locked ModuleSynchronous command by using the key sequence

(see the EscapeFunc).

ngl bestie the manpage literally leaves that one blank, that's not me being lazy, that's just the text. ๐Ÿ’€ Moving on.

ModuleTimeout timeout

Specifies how many seconds fvwm waits for a module to respond. If the module does not respond within the time limit then fvwm kills it. timeout must be greater than zero, or it is reset to the default value of 30 seconds. โญ

SendToModule modulename string

Sends an arbitrary string (no quotes required) to all modules whose alias or name matches modulename, which may contain wildcards. This only makes sense if the module is set up to understand and deal with these strings though. Can be used for module to module communication, or implementation of more complex commands in modules. Group chat but it's modules. ๐Ÿ“จ


Session Management Commands ๐ŸŒˆ

Quit

Exits fvwm, generally causing X to exit too. Sayonara. ๐Ÿ‘‹

Restart [window_manager [params]]

Causes fvwm to restart itself if window_manager is left blank, or to switch to an alternate window manager (or other fvwm version) if window_manager is specified. If the window manager is not in your default search path, then you should use the full path name for window_manager.

This command should not have a trailing ampersand. The command can have optional parameters with simple shell-like syntax. You can use ~ (which is expanded to the user's home directory) and environmental variables $VAR or ${VAR}. Here are several examples:

Key F1 R N Restart
Key F1 R N Restart fvwm1 -f .fvwmrc
Key F1 R N Restart xterm -n '"X console"' -T \"X\ console\" -e fvwm

Note, currently with multi headed displays, restart of fvwms on different screens works independently.

Restart --pass-args window_manager

The same as Restart without parameters but the name for the current window manager is replaced with the specified window_manager and original arguments are preserved.

Restart --dont-preserve-state [other-params]

The same as

Restart [other-params]

but it does not save any window states over the restart. โœจ

Without this option, Restart preserves most per-window state by writing it to a file named .fs-restart-$HOSTDISPLAY in the user's home directory. so it just quietly stashes your whole vibe in a lil file ๐Ÿ’พ

  • SaveSession โ€” tells a session manager (if one's even around) to save the session. okay but real talk: this one does not work for xsm โ€” like, xsm straight up doesn't implement this functionality, it seems. So if you're wrangling xsm from a distance, use Unix signals instead. ๐Ÿ’€
  • SaveQuitSession โ€” tells a session manager (if one's around) to save and then shut the session down. Same energy as above: does not work for xsm, because xsm doesn't implement this functionality. Use Unix signals to manage xsm remotely. signals are the group chat it actually reads ๐Ÿ“ก

โœจ Colorsets โœจ ๐ŸŽจ

Bestie, listen. Colorsets are a powerful way to control colors. They create appearance resources that get shared by fvwm and all its modules. The second you modify a colorset, every part of fvwm reacts to that change โ€” no cap. A colorset includes a foreground color, background color, shadow and highlight color (often based on the background color), and a background face (which includes images and all kinds of gradients). There's also a way to render the background face and specify other color operations. iconic tbh ๐ŸŒˆ

  • Colorset num [options] โ€” creates or modifies colorset num. Colorsets are identified by this number. The number can start at zero, and it can be a very large number. ๐Ÿ‘‘
Warning: the highest colorset number you use determines memory consumption. So like, if you define Colorset 100000, the memory for 100001 colorsets gets used. Keep your colorset numbers as small as possible, fr fr. ๐Ÿซ 

By convention, colorsets are numbered like this:

# 0 = Default colors
# 1 = Inactive windows
# 2 = Active windows
# 3 = Inactive menu entry and menu background
# 4 = Active menu entry
# 5 = greyed out menu entry (only bg used)
# 6 = module foreground and background
# 7 = hilight colors

If you need more colors and don't wanna reinvent the wheel, you can use the convention from fvwm-themes โ€” it defines the meaning of the first 40 colorsets for nearly all purposes:

http://fvwm-themes.sourceforge.net/doc/colorsets

Each colorset has four colors, an optional pixmap, and an optional shape mask. Those four colors get used by modules as the foreground, background, highlight and shadow colors. When a colorset is created it defaults to a foreground of black and background of gray. The background and foreground are marked as "average" and "contrast" (see later) so that just specifying a pixmap or gradient gives you sensible results. no extra work required, we love that โœจ

options is a comma separated list containing some of the keywords: fg, Fore, Foreground, bg, Back, Background, hi, Hilite, Hilight, sh, Shade, Shadow, fgsh, Pixmap, TiledPixmap, AspectPixmap, Transparent, RootTransparent, Shape, TiledShape, AspectShape, NoShape, ?Gradient, Tint, fgTint, bgTint, Alpha, fgAlpha, Dither, NoDither, IconTint, IconAlpha, Plain.


  • fg, Fore and Foreground โ€” take a color name as an argument and set the foreground color. The special name Contrast can be used to pick a color that contrasts well with the background color. To reset the foreground color back to the default, you literally just omit the color name. ๐Ÿ’…
  • bg, Back and Background โ€” take a color name as an argument and set the background color. They also set the highlight and shadow colors to values that give a 3d effect โ€” unless those were explicitly set with the options below. The special name Average can be used to pick a color that's the average color of the pixmap. tiny detail alert: if the pixmap is tinted with the Tint option, the tint is not taken into account when computing the average color. You should use the bgTint option to get the "real" average color. And the background color resets to the default value if you omit the color name. ๐ŸŽจ
  • hi, Hilite and Hilight โ€” take a color name as an argument and set the highlight color. If the highlight color isn't explicitly set, the default is to calculate it from the background color. To switch back to the default behavior, the color name can be omitted. โœจ
  • sh, Shade and Shadow โ€” take a color name as an argument and set the shadow color. If the shadow color isn't explicitly set, the default is to calculate it from the background color. To switch back to the default behavior, the color name can be omitted. ๐ŸŒธ
  • fgsh โ€” takes a color name as an argument and sets the color used by the shadowing font effect. See the Font Shadow Effects section of the fvwm man page. By default this color is computed from the foreground and background colors. To switch back to the default, the color name can be omitted. ๐Ÿฆ‹
  • Pixmap, TiledPixmap and AspectPixmap โ€” take a file name as an argument, search the ImagePath, and use it as the background pixmap. Any transparent parts get filled with the background color. Not specifying a file name removes any existing image from the colorset. TiledPixmap produces repeated copies of the image with no scaling, Pixmap causes the image to be stretched to fit whatever object the colorset is applied to, and AspectPixmap stretches to fit but retains the image aspect ratio. pick your fighter ๐Ÿ–ผ๏ธ
  • Transparent โ€” creates a transparent background pixmap. The pixmap is used as a window background to achieve root transparency. For this you should use the ParentalRelativity option to the Style command. A subsequent root background change may or may not be detected โ€” that depends on the program used to set the background. If you use fvwm-root, xsetbg (xli), FvwmBacker with solid or colorset colors, or a recent version of Esetroot (>= 9.2), a background change is detected. If background changes are not detected (e.g., if you use xv or xsetroot) you can force detection by using the -d option of fvwm-root:
xv -root -quit mybg.png; fvwm-root -d
Heads up, bestie: because of the way X implements transparency, no guarantees can be made that the desired effect can be achieved. The application may even crash. If you experience any problems with this option, do not use it. ๐Ÿ˜ญ

Using outline move and resize (see the OpaqueMoveSize command and the ResizeOpaque Style option) as well as setting the WindowShadeShrinks style may help. The transparency achieved with Transparent depends on whether the colorset is applied to the foreground or the background of a window. In the second case, the transparency is relative to the parent window of the window on which the colorset is defined. For example:

Colorset 12 VGradient 200 grey30 grey60
Colorset 17 Transparent
*FvwmIconMan: Colorset 12
*FvwmIconMan: PlainColorset 17

That gives you an IconMan with a vertical grey gradient background, and the buttons use the background (by transparency). To obtain a (root) transparent IconMan:

Colorset 12 Transparent
Colorset 17 Transparent
Colorset 18 Transparent
Colorset 19 Transparent

*FvwmIconMan: Colorset 12
*FvwmIconMan: PlainColorset 17
*FvwmIconMan: FocusColorset 18
*FvwmIconMan: IconColorset  19

The Colorset IconMan option defines the IconMan window background, but the PlainColorset and the FocusColorset are drawn on the foreground. So the transparency of the IconMan buttons is achieved by drawing nothing. the void is the aesthetic ๐Ÿ•ณ๏ธโœจ

Now if this IconMan is swallowed in an FvwmButtons as:

FvwmButtons:(Colorset 10, Swallow "FvwmIconMan" 'FvwmIconMan')

then FvwmIconMan becomes a child of FvwmButtons and it's transparent relative to FvwmButtons. So in this case FvwmIconMan uses Colorset 10 as background. If you want root transparency, use the RootTransparent option.

FvwmButtons, FvwmIconMan, and FvwmIdent are relatively simple. There's one main colorset option which defines the background of the window, and the other colorsets (if any) are drawn on the foreground. The case of FvwmProxy is simpler โ€” the two colorsets refer to the window backgrounds. FvwmPager is more complicated, because almost everything in the pager is windows with some parental relations (the mini windows are the child, the desktops are the parents, and all this is complicated by the hilighted page). So the colorsets apply to the background of these windows. you should experiment. ๐Ÿงช

For FvwmForm and FvwmScript the situation is similar. There's a main window (a child of the root window) which corresponds to the main colorset, and most of the widgets are windows which are children of the main window.

Tint may work or may not work with the Transparent option. When the colorset is drawn on the foreground, Tint should work. In some cases, tinting may be very slow. Tinting may work with fvwm menu (without animation). Tinting may work better if your X server has backing store enabled (try xdpyinfo to see if this is the case). There's a chance that the backing store support of your X server does not work well with the terrible hack used to Tint the ParentRelative Pixmap. So to get tinted root transparency, it's more safe to use the RootTransparent option. ๐ŸŒˆ

  • RootTransparent [ buffer ] โ€” creates a root transparent background. To make this option work, you must use an Esetroot compatible program, fvwm-root with the --retain-pixmap option, or FvwmBacker with the RetainPixmap option (and colorset or solid backgrounds). The buffer keyword is useful only when the Tint option is used too. This speeds up creation of windows which use the colorset (useful for fvwm menus) at the cost of memory usage. It also speeds up opaque move and resize, which can be unacceptably slow without buffer. However, this option may add a lot of memory to your X server (depending on the size of the image used to set the background). In summary, using outline move and resize for modules which use such a colorset may be a good idea. ๐Ÿซถ
  • Shape, TiledShape and AspectShape โ€” take a file name as an argument, search the ImagePath, and use it as the shape bitmap. TiledShape produces repeated copies of the bitmap with no scaling, Shape causes the bitmap to be stretched to fit whatever object the colorset is applied to, and AspectShape stretches to fit but retains the bitmap aspect ratio. If the file is a pixmap in xpm format, the shape mask (all opaque pixels) of the pixmap is used. For png and svg images, the shape mask is equivalent to all not completely transparent pixels (alpha > 0). ๐Ÿ‘‘
โš ๏ธ Warning bestie โš ๏ธ โ€” the way X11 does shapes, you literally cannot take back making windows shaped. Like, once it's shaped, it's shaped. You may have to restart fvwm or the shaped app. No undo. Periodt. ๐Ÿ’€
  • ?Gradient ... โ€” makes a pixmap and stretches it to fit the window. ?Gradient can be one of HGradient, VGradient, DGradient, BGradient, SGradient, CGradient, RGradient or YGradient. And the tea on the types: H is horizontal; V is vertical; D is diagonal, top-left โ†’ bottom-right; B is a backwards diagonal, bottom-left โ†’ top-right; S is concentric squares; C is concentric circles; R is a radar-like pattern; and Y is a Yin Yang style (but like, without the dots ๐Ÿ’…). For the gradient syntax itself, go check the Color Gradients section, iykyk.
  • Tint โ€” takes 2 arguments: a color and a percentage between 0 and 100. It tints the image you defined with ?Pixmap or ?Gradient with that color, using that percentage. If the image is transparent, Tint only tints the image part itself. Lowkey sad part: a colorset background set with the Transparent option can give you strange results ๐Ÿ™ˆ โ€” see the Transparent option for the deets. With no arguments, this option removes the tint.
  • fgTint โ€” takes 2 arguments, a color and a percentage between 0 and 100. It tints the color you set with fg using the specified color at that percentage. With no arguments, this option removes the tint.
  • bgTint โ€” takes 2 arguments, a color and a percentage between 0 and 100. It tints the color you set with bg using the specified color at that percentage. If the sh and hi colors aren't specified, they get recomputed from the tinted bg color. With no arguments, this option removes the tint.
  • Alpha โ€” takes a percentage between 0 and 100 as its argument. It makes fvwm merge the image defined with ?Pixmap or ?Gradient with the bg color, using that percentage. Percentage 0 = image hidden, percentage 100 = image shown as usual (no merge at all). The default is 100, and it gets restored if you give no argument.
  • fgAlpha โ€” takes a percentage between 0 and 100 as its argument. It makes fvwm merge the text and the colorset background using that percentage. Percentage 0 = text hidden, percentage 100 = text displayed as usual (no merge). Heads up: this one only does anything with fonts loaded by Xft โ€” see the Font Names and Font Loading section. Default is 100, restored if no argument is given.
  • Dither โ€” makes fvwm dither the image defined with ?Pixmap or ?Gradient. This is only useful on displays with depth less than or equal to 16 (so, displays that can only show fewer than 65537 colors at once). The dithering vibe lets you simulate having more colors than you actually do. NoDither makes fvwm not dither the images. Dither is the default if the depth is less than or equal to 8 (a screen with 256 colors or fewer). At depth 15 (32768 colors) and 16 (65536 colors), the default is NoDither โ€” but honestly this effect can still be useful with images that have a lot of close colors. Like, a fine gradient looks more smooth, fr fr.
  • IconTint โ€” takes 2 arguments, a color and a percentage between 0 and 100. It makes fvwm or a module tint the "icons" that get rendered into the colorset background, using the specified color at that percentage. And when I say "icons" I mean: fvwm Icons, fvwm menu icons, MiniIcons that represent applications in various modules, images loaded by modules (e.g., images specified by the Icon FvwmButtons button option)โ€ฆ etc. ๐Ÿ’ซ With no arguments, this option removes the icon tint.
  • IconAlpha โ€” takes a percentage between 0 and 100 as its argument. It makes fvwm merge the "icons" that are rendered into the colorset background using this percentage. The default is 100 and it's restored if no argument is given.
Note, bestie: using "Tint a_color rate" and "Alpha a" is equivalent when a = 100 and the bg color is a_color. But that equivalence does not hold for IconAlpha and IconTint, because the background can be an image or a gradient (not a uniform color background). That said, in some cases you can get (almost) the same effect by using IconTint in place of IconAlpha. And honestly that's preferable, because in general IconAlpha generates more redrawing than IconTint. Slay.
  • NoShape โ€” removes the shape mask from the colorset, while Plain removes the background pixmap or gradient.

โœจ Examples โœจ

Colorset 3 fg tan, bg navy

If necessary, this creates colorsets 0, 1, 2 and 3, and then changes colorset 3 to have a foreground of tan and a background of navy.

Colorset 3 bg "navy blue"

Changes the background color of colorset 3 to navy blue. The foreground and pixmap stay unchanged, no notes.

Colorset 3 AspectPixmap large_murky_dungeon.xpm

Causes depression. ๐Ÿ˜ญ (no but literally that's what it says, the name of that file is a whole mood)

Colorset 3 bg Average

Sets the background color and the relief colors to match the background pixmap. This is the default setting, but you must use it if a background color was specified and is now not required.

Colorset 3 YGradient 200 3 blue 1000 navy 1 blue 1000 navy

Adds a Yin Yang gradient background pixmap to colorset 3. If the background is set to average, it gets recomputed โ€” along with the foreground, if that's set to contrast.

#!/bin/sh
FvwmCommand "Colorset 7 fg navy, bg gray"
while true
do
        FvwmCommand "Colorset 7 fg gray"
        sleep 1
        FvwmCommand "Colorset 7 fg navy"
        sleep 1
done

Makes colorset 7 blink. ๐Ÿ‘‘ iconic behaviour honestly.

The color names used in colorsets are saved as fvwm variables, which you can substitute in any fvwm command. For example:

AddToFunc InitFunction
+ I Exec exec xterm -fg $[fg.cs0] -bg $[bg.cs0]

Where $[fg.cs0] is the foreground color of colorset zero. Peep the Command Expansion section for more info, bestie.


๐Ÿงผ CleanupColorsets ๐Ÿงผ

Resets a definition of all colorsets.


๐ŸŒˆ Color Gradients ๐ŸŒˆ

A color gradient is a background that gradually changes its color from one hue to a different one โ€” a whole glow-up for your windows. โœจ Color gradients can be used by various commands and modules of fvwm. There are eight types of gradients: HGradient is a horizontal gradient, VGradient is vertical, DGradient is diagonal from top left to bottom right, BGradient is a backwards diagonal from bottom left to top right, SGradient is concentric squares, CGradient is concentric circles, RGradient is a radar-like pattern and YGradient is a Yin Yang style (but without the dots).

The color gradient syntax has two forms:

?Gradient colors start-color end-color

This form specifies a linear gradient. The arguments mean: the total number of colors to allocate (between 2 and 1000), the initial color and the final color.

Example:

TitleStyle VGradient 20 rgb:b8/ce/bc rgb:5b/85/d0
?Gradient colors segments color length color [length color] ...

The second form specifies a nonlinear gradient. The arguments are: the total number of colors to allocate (between 2 and 1000), then the number of segments. For each segment, specify the starting color, a relative length, then the ending color. Each subsequent segment begins with the second color of the last segment. The lengths may be any non-negative integers. The length of one segment divided by the sum of all segments' lengths is the fraction of the colors used for that segment. Math but make it fashion ๐Ÿ’…

Examples:

Colorset 0 DGradient 128 2 lightgrey 50 blue 50 white

# 20% gradient from red to blue,
# 30% from blue to black,
# 50% from black to grey
Colorset 0 DGradient 100 3 Red 20 Blue 30 Black 50 Grey

# 50% from blue to green, then
# 50% from yellow to red
Colorset 0 HGradient 128 3 Blue 1000 Green 1 Yellow 1000 Red
Note: some gradient styles may be slow and consume huge amounts of memory, so if you run into performance problems with them, you might be better off just not using them. To improve performance you can try one or all of the following:

Turn hilighting of the active menu item off, other than the foreground color:

MenuStyle <style> Hilight3DOff, !HilightBack

Make sure sub menus don't overlap the parent menu. This can prevent menus being redrawn every time a sub menu pops up or down.

MenuStyle <style> PopupOffset 1 100

Run your X server with backing storage. If your X Server is started with the -bs option, turn it off. If not, try the -wm and +bs options:

startx -- -wm +bs

You may have to adapt this example to your system (e.g. if you use xinit to start X). Every machine is a little different, bestie, do what works for you ๐Ÿซถ


๐ŸŒ ENVIRONMENT ๐ŸŒ

The environment variables that have an effect on how fvwm operates are the following, and yes we're going through every single one:

  • DISPLAY โ€” Fvwm starts on this display, unless the -display option is given.
  • FVWM_USERDIR โ€” used to determine the user's data directory for reading and writing files. If this variable isn't already set, it gets set by fvwm to $HOME/.fvwm, which is the default user's data directory.
  • FVWM3_LOGFILE โ€” used to determine the path and filename to log debug information from fvwm3. By default, the debug log is written to $FVWM_USERDIR/fvwm3-output.log. If an absolute path is specified (starting with /) then $FVWM_USERDIR is ignored, otherwise the log is written to $FVWM_USERDIR/$FVWM3_LOGFILE.
  • FVWM_DATADIR โ€” set by fvwm to the directory containing fvwm config and module data.
  • FVWM_MODULEDIR โ€” set by fvwm to the directory containing the standard fvwm modules.
  • SESSION_MANAGER โ€” Fvwm tries to contact this session manager.
  • SESSION_MANAGER_NAME โ€” this is used mainly to determine xsm running, to work around its bug. If this variable is set to "xsm", DiscardCommand is set as xsm expects it and not as XSMP requires. If you run fvwm under xsm, you should set this variable to "xsm", otherwise old state files are not removed. ๐Ÿ˜ฌ
  • SM_SAVE_DIR โ€” if this is set, fvwm saves its session data in this directory. Otherwise it uses $HOME. Note: the state files are named .fs-?????? and normally are removed automatically when not used anymore.

๐Ÿ‘‘ AUTHORS ๐Ÿ‘‘

okay so let's give credit where credit is SO due, bestie, because this whole thing was a group project of legends. ๐Ÿ’–

  • Robert Nation โ€” the original icon, with help from many people. It's all based on twm code, which was written by Tom LaStrange.
  • Then after Robert Nation came Charles Hines โœจ
  • followed by Brady Montz ๐ŸŒธ
  • And currently fvwm is developed by a whole bunch of people on the fvwm-workers mailing list.

It's giving collaborative slay, fr fr. ๐Ÿซถ


Fvwm and all the modules, scripts and other files coming with the distribution are subject to the GNU General Public License (GPL). ๐ŸŽ€

Please refer to the COPYING file that came with fvwm for details. iykyk โ€” read the license, bestie, it's literally right there. ๐Ÿ’…


๐Ÿ› BUGS ๐Ÿ›

Found a bug? not the vibe but also please tell us!! Bug reports can be sent to the fvwm-workers mailing list at:

fvwm-workers@fvwm.org

And the official fvwm homepage is:

http://fvwm.org/

and that's the whole page, bestie!! ๐ŸŽ‰ You just read the entirety of FVWM3ALL(1) from the fvwm distribution, dated 2026-06-28. ๐Ÿ’– Go forth and rice your desktop, you absolute main character. No cap, you ate. ๐Ÿ‘‘โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from