FvwmScript(1)
π FvwmScript(1) π
okay bestie, this is FvwmScript(1) from the Fvwm Modules section π part 1 of 4, so get comfy β¨
β¨ NAME β¨
FvwmScript β module to build graphic user interface πΌοΈ
πΈ SYNOPSIS πΈ
FvwmScript must be spawned by Fvwm. It's not going to work from the command line.
ngl this one's a hard rule π FvwmScript must be spawned by Fvwm, and it will not work from the command line.
π¦ DESCRIPTION π¦
FvwmScript is a module that lets you build so many graphical apps β¨ like desktop accessories, button panels with pop up menus, modal dialogs... literally it's giving everything. When it starts up, it reads the file you name on the command line, and that file is the script. The script is not part of Fvwm's configuration file, so keep them separate, periodt π
An FvwmScript script is fully controllable with the keyboard, which is so iconic π«Ά (Shift)-Tab circulates around the widgets, Return simulates a mouse click, the arrows move the cursor or change the values of the widget, and Escape "cancels" for Menu and PopupMenu.
π§ INVOCATION π§
You can invoke it by inserting the line Module FvwmScript name_of_script in the .fvwm2rc file π If name_of_script starts with a slash, it's a fully qualified path and that file gets read. If it doesn't start with a slash, FvwmScript is gonna check a few different places π If .fvwm2rc has the command line *FvwmScript: Path path_of_the_script_directory, FvwmScript tries that directory first. If that doesn't work, it tries the system configuration directory and then the user configuration directory, same as the "Read" command in the fvwm man page.
The command to start FvwmScript can sit on a line by itself if you want it spawned during fvwm's initialization π Or you can bind it to a menu, a mouse button, or a keystroke so it shows up later on.
π CONFIGURATION OPTIONS π
These commands work in the config file (check fvwm(1), section MODULE COMMANDS, for the deets) π¦ They only kick in if the matching script commands aren't used in the script.
*FvwmScript: DefaultFont fontβ sets the default font π€ If you don't set it here or with the Font command in the script, the fixed font is assumed.*FvwmScript: DefaultFore colorβ sets the default foreground color π¨ If it's not set here or with the ForeColor command in the script, black is used.*FvwmScript: DefaultBack colorβ sets the default background color π©Ά If it's not set here or with the BackColor command in the script, grey85 is used.*FvwmScript: DefaultHilight colorβ sets the default hilight color β¨ If it's not set here or with the HilightColor command in the script, grey100 is used.*FvwmScript: DefaultShadow colorβ sets the default shadow color π If it's not set here or with the ShadowColor command in the script, grey55 is used.*FvwmScript: DefaultColorset colorsetβ tells the module to use colorsetcolorsetas its default colorset π
π ANATOMY OF A SCRIPT π
FvwmScript uses its own programming language π A script has five parts, and I'm obsessed with how they're organized:
- Heading β general characteristics of the window and default properties for all widgets.
- Initialisation β instructions that run at startup.
- Periodic tasks β instructions that run every second.
- Quit function β instructions that run when the script exits.
- Widget descriptions β the last part, where the widgets live.
A widget can be one of eleven types of items π§ text labels, single-line text inputs, radio buttons, checkbox, push buttons, horizontal and vertical scrollbars, rectangles, pop up menus, swallowexecs, and mini scrollbars.
π HEADING OF A SCRIPT π
The syntax is as follows π«§
WindowTitle stringβ sets the window title πͺWindowSize width heightβ sets the window size.widthandheightare numerical values πWindowPosition x yβ sets the window position.xandyare numerical values πForeColor {color}β sets the default foreground color for all widgets π¨BackColor {color}β sets the default background color for all widgets π©·HilightColor {color}β sets the default hilight color for all widgets β¨ShadowColor {color}β sets the default shadow color for all widgets πColorset {n}β sets the default colorset for all widgets πΈFont {font}β sets the default font for all widgets π€UseGettext [locale_path]β enables the gettext mechanism, which theWindowLocaleTitle,LocaleTitle, andChangeLocaleTitleinstructions and theGettextfunction use π If you don't give an argument, the default FvwmScript locale catalog gets used. That catalog lives under the locale fvwm installation directory, and the text domain isFvwmScript(install_prefix/share/locale/*/LC_MESSAGES/FvwmScript.mo). You can reset this catalog or add some catalogs the exact same way as theLocalePathfvwm command (see the fvwm manual page) π«Ά This instruction should be placed before theWindowLocaleTitleinstruction, no skipping!WindowLocaleTitle stringβ sets the window title, but uses the locale catalog(s) defined withUseGettextπ
Part 2 is coming up next with the initialisation, periodic tasks, quit function, and widget stuff ππ₯
β¨ LIST OF WIDGETS β¨
okay bestie, there are fifteen types of widgets π let's go through them one by one, no cap π«Ά
π CheckBox
Displays a check box with a string next to it β
Title: the title of the check box.Value: ifValueis equal to1, the box is checked. Otherwise it is not.
The Size property is ignored π
π¦ HDipstick
Displays a horizontal dipstick. This widget can be used to display disk usage πΎ
Value: specify the current value of the dipstick.MinValue: specify the minimum value of the dipstick.MaxValue: specify the maximum value of the dipstick.
A minimum size of 30x11 is imposed π
πΈ HScrollBar
Displays a horizontal scrollbar, lowkey iconic π
Value: position of the thumb.MaxValue: upper limit ofValue.MinValue: lower limit ofValue.
The height property is ignored and a minimum width is imposed. The width should be at least the range plus 37 if you want every value to be selectable. For example, a min of 0 and a max of 10 has a range of 11, so it should have a minimum width of 48 β¨
π§ ItemDraw
Displays an icon and/or a string πΌοΈ
Title: string to display.Icon: icon to display.MaxValue: x coordinate of the cursor.MinValue: y coordinate of the cursor.
The size is made large enough to contain the title and/or the icon.
π List
Displays a list. The List lets the user choose between various options π
Value: specify which option is selected.MinValue: first visible option.Title: the title contains the options displayed in the list. The syntax is the following:{Option 1|Option 2|...|Option N}. All menus are displayed at the top of the window.
A minimum height of three items is imposed, and the width is made to be at least 108 π
π Menu
Displays a menu which lets the user choose an option. Items of type Menu are laid out from left to right along the top of the window. The size and position properties are ignored, so no babysitting π
ββοΈ
Value: specify which option is selected.Title: the title contains the options displayed in the menu. The syntax is the following:{Option 1|Option 2|...|Option N}.
π₯ MiniScroll
Displays a very small vertical scrollbar π€
Value: position of the thumb.MaxValue: upper limit ofValue.MinValue: lower limit ofValue.
The size is set to 19x34 π
π PopupMenu
Displays a pop up menu π«§
Value: specify what option is selected.Title: the title has the following syntax:{Option 1|Option 2|...|Option N}."Option 1|Option 2|...|Option N"is the pop up menu which is displayed when the mouse button is pressed.
The size property is ignored.
π PushButton
Displays a push button with an icon and/or a string. It's giving clickable π±οΈ
Title: this string has the following syntax{Title of the button|Option 1|Option 2|Option3|...|Option N}."Option 1|Option 2|...|Option N"is the pop up menu which is displayed when the right button is pressed.Icon: icon to display.
The button is made large enough to fit the icon and or label.
π¦ RadioButton
Displays a radio button with a string π
Title: title of the radio button.Value: ifValueis equal to1, the box is checked. Otherwise it is not.
The size property is ignored.
π©· Rectangle
Displays a rectangle. This type of widget can be used to decorate the window πΌοΈβ¨
π¦’ SwallowExec
This type of widget causes FvwmScript to spawn a process, and capture the first window whose name or resource is equal to Title, then display it in the script window. Main character energy π¬
Title: specify the window name to be captured and displayed in the script window.SwallowExec: specify the command line to execute to spawn the process. Modules can also be swallowed π§Value: specify the look of the border. Possible values:-1,0,1.
The size is made to be at least 30x30 π
π«§ TextField
Displays a text input field. The text input field can be used to edit a single-line string β¨οΈ
Title: content of the text field.Value: position of the insert point.MinValue: position of the end of the selection.MaxValue: first visible character of the title.
The height property is ignored. The width is made to be at least 40 pixels wider than the initial contents.
π· VDipstick
Displays a vertical dipstick π
Value: specify the current value of the dipstick.MinValue: specify the minimum value of the dipstick.MaxValue: specify the maximum value of the dipstick.
The size is made to be at least 11x30.
πͺ VScrollBar
Displays a vertical scrollbar π
Value: position of the thumb.MaxValue: upper limit ofValue.MinValue: lower limit ofValue.
The width property is ignored and a minimum height is imposed. The height should be at least the range plus 37 if you want every value to be selectable. For example, a min of 0 and a max of 10 has a range of 11, so it should have a minimum height of 48 π«Ά
β¨ INSTRUCTIONS β¨
here's the rundown on every instruction, so take notes bestie π
HideWidget id: hide the widget numberedidπ«₯ShowWidget id: show the widget numberedidπChangeValue id1 id2: set the value of the widget numberedid1toid2.ChangeMaxValue id1 id2: set the maximum value of the widget numberedid1toid2.ChangeMinValue id1 id2: set the minimum value of the widget numberedid1toid2.ChangeTitle id1 id2: set the title of the widget numberedid1toid2.ChangeWindowTitle string: set the title of the window tostring.ChangeWindowTitleFromArg numarg: set the title of the window to the value of thenumarg-th script argument π·οΈChangeLocaleTitle id1 id2: same vibe asChangeTitle, but it uses the locale catalog(s) defined withUseGettextπChangeIcon id1 id2: set the icon of the widget numberedid1toid2.ChangeForeColor id1 {color}: set the foreground color of the widget numberedid1to{color}.ChangeBackColor id1 {color}: set the background color of the widget numberedid1to{color}.ChangeColorSet id1 id2: set the colorset of the widget numberedid1toid2. Specifying widget0sets the main window colorset πChangePosition id1 x y: move the widget numberedid1to position(x,y).ChangeSize id1 width height: set the size of the widget numberedid1to(width,height).ChangeFont id1 newfont: set the font of the widget numberedid1tonewfont.WarpPointer id: warp the mouse pointer into the widget numberedidπ±οΈWriteToFile filename {str1} {str2} etc: write to the filefilenamethe string made by concatenating all the argumentsstr1,str2, etc. πDo {command args}: execute the fvwm command inside theDoblock. Any fvwm command described in thefvwm2man page can be used. Commands are sent from this module to the fvwm main program for processing. The length of the command and arguments cannot exceed988characters.
Heads up, theDolimit is988characters total, so keep those commands short and sweet π
Set $var={str1} {str2} etc: concatenate all the arguments into one string and set the variable$varto that string π§Quit: quit the program πSendSignal id1 id2: send a message numberedid2to widgetid1π¨SendToScript id_script {str11} {str2} etc: send a message to the script identified byid_script. The message is the concatenation ofstr1,str2, and so on.Key Keyname Modifier id sig str1 str2 etc: binds a keyboard key to the instructionSendSignal id sig, and sets the "last string" to the concatenation ofstr1,str2, and so on (see theLastStringfunction). TheKeynameandModifiersfields are defined the same way as in the fvwmKeycommand β¨οΈπ
β¨ ARGUMENTS β¨
most commands take arguments, and there are two kinds: numbers and strings π’π€. A numerical argument is a value between -32000 and +32000. A string is always surrounded with braces {}. Variables always begin with the character $ and can contain both numbers and strings, so they're super flexible π¦
β¨ FUNCTIONS β¨
okay bestie, functions are where the script actually gets to think π§ π All functions take arguments, and they can hand back a string or a number. The syntax is always:
(function argument1 argument2 etc)
Here's the complete list, no cap π
(GetTitle id)
Gives you the title of the widget numbered id π
(GetValue id)
Gives you the current value of the widget numbered id β¨
(GetMinValue id)
Gives you the current Min value of the widget numbered id π
(GetMaxValue id)
Gives you the current Max value of the widget numbered id π
(GetFore id)
Gives you the current RGB foreground value of the widget numbered id, in the hex format RRGGBB π¨
(GetBack id)
Gives you the current RGB background value of the widget numbered id, in the hex format RRGGBB πΈ
(GetHilight id)
Gives you the current RGB hilight value of the widget numbered id, in the hex format RRGGBB β¨
(GetShadow id)
Gives you the current RGB shadow value of the widget numbered id, in the hex format RRGGBB π
(GetOutput {str} int1 int2)
This one is lowkey iconic π₯ It runs the command str, grabs its standard output, and returns the word sitting on line int1 and in position int2. If int2 is -1, you get the whole line back instead.
(NumToHex int)
Turns int into its hexadecimal value π¦
(HexToNum {str})
Turns str into its decimal value. Heads up, str has to be a hexadecimal value or it's not gonna work π
(Add int1 int2)
Returns the result of (int1+int2) β
(Mult int1 int2)
Returns the result of (int1*int2) βοΈ
(Div int1 int2)
Returns the result of (int1/int2) β
(StrCopy {str} int1 int2)
Returns the chunk of string that sits between position int1 and position int2. For example, (StrCopy {Hello} 1 2) returns {He} π
(LaunchScript {str})
This launches the script named str and gives you back an identification number π§ You need that number to use SendToScript and ReceiveFromScript. The string str holds the script name plus some arguments.
(GetScriptArgument {int})
Returns the argument script that got passed in through LaunchScript. If int is equal to zero, you get the name of the script instead π
(GetScriptFather)
Returns the identification number of the script father π
(ReceivFromScript {int})
Returns the message sent by the script numbered int π
(RemainderOfDiv {int1 int2}): t
Returns the remainder of the division (int1/int2) π
(GetTime)
Returns the time in seconds β°
(GetPid)
Returns the process id of the script π
(Gettext {str})
Returns the translation of str, using the locale catalog(s) you set up with UseGettext π
(SendMsgAndGet {comId} {cmd} bool)
This is the one for chatting with external programs π«Ά It sends the command cmd with identifier comId to an external program that's ready to talk using a protocol that's specific to FvwmScript.
If bool is 0, FvwmScript doesn't wait for an answer. The returned value is 1 if the message made it to the external program, and 0 if it didn't.
If bool is 1, FvwmScript waits for an answer, and the return value is that answer (a line of no more than 32000 characters). If the communication fails, the returned value is 0.
See the section A COMMUNICATION PROTOCOL for a description of the communication protocol used.
(Parse {str} int)
Here, str has to look like this:
X1S1X2S2X3S3...SnXn
The Xn are numbers made of four decimal digits, and each Sn is a string of length exactly Xn. The returned value is the string Sint.
If int is out of range (e.g., >n), you get the empty string back. If str doesn't match that shape, the return value is unpredictable, bestie π (though on average it's empty).
This one is super useful for handling strings that come back from SendMsgAndGet π
(LastString)
This returns the "current working string" for the Key instruction and the SendString command (check the COMMANDS section). At startup it's empty. But when a Key binding gets detected (or a SendString command gets received), the string is set to whatever string is associated with that instruction (or with that command) β¨
π CONDITIONAL LOOPS π
There are three kinds of conditional loops, and we're about to meet all of them π¦ First up, the If-Then-Else instruction, which looks like this:
If $ToDo=={Open xcalc} Then
Do {Exec xcalc &} # List of instructions
Else
Begin
Do {Exec killall xcalc &} # List of instructions
Do {Exec echo xcalc killed > /dev/console}
End
The second part, Else-Begin-End, is optional. If the loop only has one instruction in it, you can skip Begin and End entirely π
Next is the While-Do instruction:
While $i<5 Do
Begin
Set $i=(Add i 1) # List of instructions
End
Quick rule to remember: two strings get compared with ==, and two numbers get compared with <, <=, ==, >=, or > π₯
Last but not least, the For-Do-Begin-End loop:
For $i=1 To 20 Do
Begin
Do {Exec xcalc &} # List of instructions
End
π COMMANDS π
The following fvwm command can be run at any time, so go wild πΈ
SendToModule ScriptName SendString id sig str
It sends the string to any module whose alias or name matches ScriptName π
SendString id sig str
When an FvwmScript gets a message like this, it sends the signal numbered sig to the Widget id, and the string str can be grabbed with the LastString function. Let's do an example, because examples are everything π₯°
Say you've got a script called MyScript with this widget:
Widget 50
Property
Type PushButton
Title {Quit}
...
Main
Case message of
SingleClic:
Begin
Quit
End
1 :
Begin
Set $str = (LastString)
If $str == {Quit} Then
Quit
Else
ChangeTitle 33 $str
End
End
Then this command:
SendToModule MyScript SendString 50 1 str
forces MyScript to exit if str is equal to "Quit". And if it isn't? It changes the title of Widget 33 to str instead π¦
This command can be used to change the window title π
SendToModule ScriptName ChangeWindowTitle newTitle [oldTitle]
It makes any module whose alias or name matches ScriptName change its associated window title to newTitle. The optional argument oldTitle is useful when there are several instances of the same script. It lets you avoid renaming all of those instances, by naming the window that belongs to the target script (see the example below) π―ββοΈ
+ I Module FvwmScript FvwmStorageSend "/dev/hda6"
+ I Wait FvwmStorageSend
+ I SendToModule FvwmStorageSend ChangeWindowTitle HDA6
+ I Module FvwmScript FvwmStorageSend "/dev/hda1"
+ I Wait FvwmStorageSend
+ I SendToModule FvwmStorageSend ChangeWindowTitle HDA1 FvwmStorageSend
Without the FvwmStorageSend argument in that last case, the SendToModule command would've changed the name of both instances of FvwmStorageSend to HDA1 π So yeah, don't skip that argument.
π¦ EXAMPLES π¦
You'll find example scripts in the fvwm configuration directory π
FvwmScript-BellSetup, FvwmScript-KeyboardSetup, FvwmScript-PointerSetup and FvwmScript-ScreenSetup are a set of scripts that tweak X settings π±οΈ They save your preferences into a file named ~/.xinit-fvwmrc. (If you want a different file name, pass it in as the first argument of the script.) If you want these preferences loaded on every startup, add the line ".xinit-fvwmrc" to your .xinitrc (or .xsession) file before you start fvwm β¨
FvwmScript-BaseConfig is a big one π It changes fvwm's focus and paging mouse policy, window placement, opacity, and other features of the move and resize commands, plus snap attraction and shading animation. It saves your preferences into a file named .FvwmBaseConfig in the user's data directory (that's $HOME/.fvwm, or $FVWM_USERDIR if it's set). To load these preferences on every startup, add the line "Read .FvwmBaseConfig" to your fvwm configuration file. Want a different file name? Give it as the first argument of the script.
When you click Ok or Apply, an fvwm function called BaseConfigOkFunc or BaseConfigApplyFunc gets called, if you've defined it. This is handy for reloading application styles that the script has wiped out. For example: AddToFunc BaseConfigOkFunc I Read MyAppStyle π«Ά
FvwmScript-Buttons is a buttons panel that can replace FvwmButtons. It supports popup menus and requires xload, xclock, FvwmPager, and TkDesk π₯ FvwmScript-Colorset lets you edit your colorset π¨ FvwmScript-Date lets you set the date and time β° FvwmScript-FileBrowser is a file browser that the other scripts use behind the scenes π FvwmScript-Find is an elementary front-end to find π FvwmScript-Quit lets you quit fvwm, restart fvwm or some other window manager, or shut down and reboot the computer π FvwmScript-ScreenDump is a screen dumper πΈ And FvwmScript-WidgetDemo is a pure example script π See the next section for FvwmScript-ComExample π
β¨ A COMMUNICATION PROTOCOL β¨
okay so FvwmScript is a weak (but simple) programming language π bestie, if you're dealing with a LOT of data or complex algorithms, don't force it. Hand that work to an external program (perl, for example) and then "send" the info you need into your FvwmScript script π§. There are three ways to do this:
- GetOutput πΈ: simple, but you have to rerun the external program every single time you want info from it, and that can cause performance problems π¬
- SendMsgAndGet π¦: this one extends FvwmScript so any programming language that can deal with named pipes (fifos) can join the party. This section is all about it π
- fvwm-themes-com π: this comes from the fvwm-themes package. Ngl, SendMsgAndGet is basically an implementation of fvwm-themes-com inside FvwmScript, and it gives better performance β¨
Basically, you start an "external" program (the program for short) from your FvwmScript script (the script for short). The program runs in the background, and you use the SendMsgAndGet function in your script to ask questions or give instructions π«Ά. The program has to strictly follow a certain communication protocol, no exceptions π.
First up, there's an identifier called comId for the communication. For a good implementation, it should contain the process id of the script. So use the GetPid function and pass the comId to the program via an option π₯.
The protocol uses two fifos in the fvwm user directory, named .tmp-com-in-comId and .tmp-com-out-comId. The program should create and listen on the .tmp-com-in-comId fifo. Then, when FvwmScript runs a function like this:
Set $answer = (SendMsgAndGet {comId} {cmd} bool)
FvwmScript writes the cmd onto that in fifo π. The program reads it and runs the matching action. It should remove the in fifo so multiple communications can happen π
Now the bool part, which is lowkey the most important bit:
- If bool is
0, FvwmScript does not wait for an answer. It returns1if the previous actions succeeded and0if they failed. In that case, the program should "go back" to the in fifo π - If bool is
1, FvwmScript waits 20 sec for an answer from the program and then returns that answer to the script. Note that bool is not passed to the program, because the program has to know which commands need an answer on its own π§
To answer, the program creates the .tmp-com-out-comId fifo and writes the answer on it. It should wait until FvwmScript reads the answer, then remove the out fifo and go back to the in fifo π. The answer should be one line of no more than 32000 characters. If you need multiple lines, take a look at the Parse function so they get handled as one line β¨
A simple way to understand this protocol, and to write scripts and programs that use it, is to check out the example FvwmScript-ComExample and fvwm-script-ComExample.pl. Both can be found in the fvwm data directory. (not useful) π Also, this implementation of the protocol is smart enough to handle questions like: What to do if the script exits for a bad reason? What to do if the program exits for a bad reason? ...etc. π§
π BUGS π
FvwmScript crashes if widgets are accessed that have not been defined. Don't do it, bestie π
π©βπ» AUTHOR π©βπ»
Frederic Cordier (cordie97@cui.unige.ch or f-cord96@univ-lyon1.fr) π
π«Ά CONTRIBUTOR π«Ά
Eddy J. Gurney (eddy@gizmo.aa.ans.net) πΈ
That's the whole page, bestie π Source: 3rd Berkeley Distribution, version 2.7.0, dated 19 October 2022 π¦ FvwmScript(1) signing off π β¨
π¦ where this page comes from
- debian bookworm: fvwm 1:2.7.0-2 Β· GPL-2.0-only
- debian trixie: fvwm 1:2.7.0-3 Β· GPL-2.0-or-later
- ubuntu noble: fvwm 1:2.7.0-2build2 Β· GPL-2.0-only
- ubuntu questing: fvwm 1:2.7.0-3
- ubuntu resolute: fvwm 1:2.7.0-3build1 Β· GPL-2.0-or-later
- ubuntu stonking: fvwm 1:2.7.0-3build1 Β· GPL-2.0-or-later
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms