FvwmPerl(1)

๐Ÿ’– FvwmPerl(1) ๐Ÿ’–

Bestie, this is the Fvwm Modules page for the FvwmPerl manipulator and preprocessor ๐Ÿงš


โœจ NAME โœจ

FvwmPerl, the fvwm perl manipulator and preprocessor ๐ŸŒธ

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

okay so FvwmPerl is supposed to be spawned by fvwm(1) for normal functionality ๐Ÿ’…

To run this module, drop this command somewhere in your config:

Module FvwmPerl [params]

or this one:

ModuleSynchronize FvwmPerl [params]

use the second one if you want to start sending commands to FvwmPerl right away ๐Ÿฆ‹

๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

This module is giving extend fvwm commands with perl scripting power energy โญ It lets you embed perl expressions in your fvwm config files and build fvwm commands out of them. main character energy, literally ๐Ÿ‘‘

๐Ÿฆ‹ INVOCATION ๐Ÿฆ‹

if you want the unique and persistent instance of FvwmPerl, the move is to call it from the StartFunction ๐ŸŒˆ You can call it from the top too, but that comes with some issues that we're not getting into here ๐Ÿ’€

AddToFunc StartFunction I Module FvwmPerl

there are a bunch of command line switches:

FvwmPerl [ --eval line ] [ --load file ] [ --preprocess [ --quote char ]
[ --winid wid ] [ --cmd ] [ --nosend ] [ --noremove ] [ line | file ] ]
[ --export [names] ] [ --stay ] [ --nolock ] [ alias ]

long switches can be shortened down to their one-letter versions, so you don't have to type the whole thing every time ๐Ÿซถ

  • -e, --eval line โ€” evaluates the perl code you hand it ๐Ÿ”ฅ
  • -l, --load file โ€” evaluates perl code living in the file you point at ๐Ÿ“œ
  • -p, --preprocess [ file ] โ€” preprocesses the fvwm config file you give it ๐ŸŒธ

these next 5 options only work together with --preprocess, so don't try them solo ๐Ÿ™ˆ

  • -c, --cmd line โ€” an fvwm command to preprocess instead of a file ๐Ÿ’–
  • -q, --quote char โ€” swaps out the default '%' quote for a different one โœจ
  • -w, --winid wid โ€” sets an explicit window context ๐Ÿช„ The wid should start with a digit, and it can be in oct or hex form. Whatever you pass here overwrites any implicit window context that's floating around.
  • --nosend โ€” doesn't send the preprocessed file over to fvwm to read. The default is to send it. This is super handy for preprocessing non fvwm config files ๐Ÿ“
  • --noremove โ€” keeps the preprocessed file around after it's been sent to fvwm. The default is to remove it. Useful for debugging ๐Ÿ›

and now the rest of the crew ๐Ÿ’…

  • -x, --export [names] โ€” defines fvwm shortcut functions. By default you get two, named "Eval" and ".". This option implies --stay, so it sticks around ๐Ÿงš
  • -s, --stay โ€” keeps things going after --eval, --load or --preprocess have been processed. By default the module is not persistent in this case, which is the same as saying --nostay is assumed ๐Ÿฆ‹
  • --nolock โ€” when one of the 3 action options is given, this option unlocks fvwm immediately. By default the requested action runs synchronously. That only makes a difference when you invoke it like this:
ModuleSynchronous FvwmPerl --preprocess someconfig.ppp

if --nolock is added there, ModuleSynchronous returns right away. Just know that Module returns immediately regardless of this option ๐ŸŒธ

๐Ÿ‘‘ USING ALIAS ๐Ÿ‘‘

aliases let you run several module invocations at once and work with each one separately. here's a little example, slay ๐Ÿ’–

ModuleSynchronous FvwmPerl FvwmPerl-JustTest
SendToModule FvwmPerl-JustTest eval $a = 2 + 2; $b = $a
SendToModule FvwmPerl-JustTest eval cmd("Echo 2 + 2 = $b")
KillModule FvwmPerl FvwmPerl-JustTest

๐Ÿ”ฅ PREPROCESSING EXAMPLE ๐Ÿ”ฅ

one of the most effective preprocessing moves is to pass your whole fvwm config, with the embedded perl code, to "FvwmPerl --preprocess" ๐Ÿซถ Another option is to write a perl script that spits out fvwm commands and sends them off to run, and you can load that script with "FvwmPerl --load" โœจ There are also in-between solutions that only preprocess separate config lines, or that run separate perl commands which produce fvwm commands ๐Ÿฆ‹

this snippet adds arithmetic and string scripting to the lines that need it ๐Ÿงฎ To use it, make FvwmPerl your very first command so that other commands can be asked to get preprocessed ๐Ÿ’…

ModuleSynchronize FvwmPerl

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

. Exec exec xterm -name xterm-%{++$i}%   # use unique name

. GotoDesk 0 %{ $[desk.n] + 1 }%         # go to next desk

. Exec exec %{ -x "/usr/bin/X11/aterm" ? "aterm" : "xterm" }% -sb

# center a window
Next (MyWindow) . Move \
  %{($WIDTH - $[w.width]) / 2}%p %{($HEIGHT - $[w.height]) / 2}%p

. Exec exec xmessage %{2 + 2}%           # simple calculator

. %{main::show_message(2 + 2, "Yet another Calculator"); ""}%

โœจ FUNCTIONS โœจ

okay so these are the functions your perl code can call ๐Ÿ’… they're lowkey the best part of the whole module ๐Ÿซถ

cmd($fvwm_command)

bestie, this one's a multitasker ๐Ÿฆ‹ during an eval or load, it sends the string $fvwm_command back to fvwm. during a preprocess, it tacks $fvwm_command onto the output of the embedded perl code instead ๐ŸŽ€

do_eval($perl_code)

this is basically the eval functionality but on the string $perl_code, same as described above โœจ

load($filename)

same energy as the load functionality, but it works on the file $filename ๐ŸŒธ

preprocess(@params, ["-c $command"] [$filename])

this one is the preprocess functionality with whatever parameters you hand it, plus the file $filename we talked about earlier ๐Ÿ’œ

export($func_names, [$do_unexport])

the export functionality, using the $func_names you give it ๐Ÿ”ฅ if the second parameter is true, it'll unexport the function names instead, so it's giving two jobs in one ๐Ÿ‘‘

function names can be separated by commas or/and whitespace, so do whatever is cutest to you ๐Ÿ“ and if $func_names is empty, it just assumes the functions "Eval" and "." ๐Ÿงš

stop()

terminates the module. bye bye ๐Ÿ‘‹๐Ÿ’€

skip()

skips the rest of the event callback code. the module goes right back to listening for new module events ๐Ÿฆ‹

unlock()

this one unsynchronizes the event callback from fvwm ๐Ÿซถ it's super useful for preventing deadlocks. normally fvwm kills a non-responding module if the event callback isn't done within ModuleTimeout seconds, and unlock stops that from happening โœจ

here's an example that makes FvwmPerl suspend for one minute:

SendModule FvwmPerl eval unlock(); sleep(60);
โš ๏ธ be careful with this one, bestie ๐Ÿ˜ญ verify that there's no way fvwm can send a new message while the module is busy, and that fvwm won't stay locked on that new message for too long. if you need long-lasting operations, check out the detach solution too ๐Ÿ’–

detach()

this one forks and detaches the rest of the event callback code from the main process ๐Ÿงš it's a lifesaver if your callback takes forever, since the work can happen in the detached child and the module won't get killed ๐Ÿ’… the detached child can still send commands to fvwm (but don't rely on that, ngl), and it won't receive events obviously. it exits right after the callback finishes ๐Ÿ’€

๐Ÿšจ if you use detach(), it's better to only send commands to fvwm from one process, either the main one or the detached one. doing both often causes conflicts, so don't be that girl ๐Ÿ™ˆ

show_message($msg, $title[, $use_stderr_too=1])

shows a dialog window with your message, using whichever X tool it finds on the system ๐ŸŒˆ

see FVWM::Module::Toolkit::show_message for more info ๐Ÿ’œ


โœจ VARIABLES โœจ

there are a bunch of global variables in the main namespace you can use in your perl code, and they're all giving main character energy ๐Ÿ‘‘

$a, $b, ... $h
@a, @b, ... @h
%a, %b, ... %h

they all start out as the empty value ๐Ÿซง you can use them to store state between different calls to FvwmPerl actions (eval and load) ๐Ÿฆ‹

if you want more readable variable names, you've got options ๐Ÿ’– you can write no strict 'vars'; at the start of every perl code, or use a hash, like this:

$h{id} = $h{first_name} . " " . $h{second_name}

or use a package name, like this:

@MyMenu::terminals = qw( xterm rxvt );
$MyMenu::item_num = @MyMenu::terminals;

also there may be a configuration option to turn strictness on and off, so keep an eye out ๐Ÿ‘€โœจ


โœจ MESSAGES โœจ

FvwmPerl can receive messages using the fvwm command SendToModule ๐Ÿ’Œ the names, meanings and parameters of the messages are the same as the corresponding actions we covered earlier, so no new homework ๐ŸŽ€

a stop message makes the module quit ๐Ÿซก

a message unexport [func-names] undoes the effect of export (that's the one from the ACTIONS section) ๐Ÿ”„

and a dump message dumps the contents of the changed variables... well, not yet ๐Ÿ™ˆ so don't hold your breath ๐Ÿ’€


โœจ EXAMPLES โœจ

okay, first up is a simple test ๐Ÿงช

SendToModule FvwmPerl eval $h{dir} = $ENV{HOME}
SendToModule FvwmPerl eval load($h{dir} . "/test.fpl")
SendToModule FvwmPerl load $[HOME]/test.fpl
SendToModule FvwmPerl preprocess config.ppp
SendToModule FvwmPerl export Eval,PerlEval,PerlLoad,PerlPP
SendToModule FvwmPerl unexport PerlEval,PerlLoad,PerlPP
SendToModule FvwmPerl stop

this next one handles root backgrounds in fvwmrc ๐ŸŒ… all of these commands can go in StartFunction ๐Ÿซถ

Module FvwmPerl --export PerlEval

# find all background pixmaps for a later use
PerlEval $a = $ENV{HOME} . "/bg"; \
  opendir DIR, $a; @b = grep { /xpm$/ } readdir(DIR); closedir DIR

# build a menu of background pixmaps
AddToMenu MyBackgrounds "My Backgrounds" Title
PerlEval foreach $b (@b) \
  { cmd("AddToMenu MyBackgrounds '$b' Exec fvwm-root $a/$b") }

# choose a random background to load on start-up
PerlEval cmd("AddToFunc \
  InitFunction + I Exec exec fvwm-root $a/" . $b[int(random(@b))])

โœจ ESCAPING โœจ

okay this part is important, bestie ๐Ÿšจ SendToModule, just like any other fvwm command, expands several dollar prefixed variables ๐Ÿ’ฒ and that can clash with the dollars perl uses ๐Ÿ˜ญ you can avoid this by putting a leading dash in front of SendToModule. each pair below is equivalent ๐Ÿ’–

SendToModule FvwmPerl eval $$d = "$[DISPLAY]"
-SendToModule FvwmPerl eval $d = "$ENV{DISPLAY}"

SendToModule FvwmPerl eval \
    cmd("Echo desk=$d, display=$$d")
SendToModule FvwmPerl preprocess -c \
    Echo desk=%("$d")%, display=%{$$d}%

another way to dodge escaping special symbols like dollars and backslashes is to make a perl file in ~/.fvwm and load it ๐Ÿงš

SendToModule FvwmPerl load build-menus.fpl

and if you need to preprocess a command that starts with a dash, precede it with -- ๐ŸŽ€

# this prints the current desk, i.e. "0"
SendToModule FvwmPerl preprocess -c Echo "$%{$a = "c"; ++$a}%"
# this prints "$d"
SendToModule FvwmPerl preprocess -c -- -Echo "$%{"d"}%"
# this prints "$d" (SendToModule expands $$ to $)
SendToModule FvwmPerl preprocess -c -- -Echo "$$%{"d"}%"
# this prints "$$d"
-SendToModule FvwmPerl preprocess -c -- -Echo "$$%{"d"}%"

and once again, it's honestly suggested to put your commands into a file and preprocess the file instead ๐Ÿซถ


โœจ CAVEATS โœจ

FvwmPerl is written in perl and deals with perl, so it follows the famous perl motto: "There's more than one way to do it" ๐ŸŒˆ the choice is yours, queen ๐Ÿ‘‘

here are more pairs of equivalent lines ๐Ÿฆ‹

Module FvwmPerl --load "my.fpl" --stay
Module FvwmPerl -e 'load("my.fpl")' -s

SendToModule FvwmPerl preprocess --quote '@' my.ppp
SendToModule FvwmPerl eval preprocess({quote => '@'}, "my.ppp");
โš ๏ธ warning, you can change the way FvwmPerl works by evaluating the right perl code. this is considered a feature, not a bug ๐Ÿ’… but PLEASE don't do this, bestie ๐Ÿ˜ญ write your own fvwm module in perl instead ๐Ÿ™

โœจ SEE ALSO โœจ

the fvwm(1) man page describes all the available commands ๐Ÿ“–

basically, in your perl code you can use any function or class method from the perl library installed with fvwm. check out the man pages of the perl packages General::FileSystem, General::Parse and FVWM::Module ๐Ÿ’œ


โœจ AUTHOR โœจ

this module was made by Mikhael Goikhman <migo@homemail.com> ๐Ÿซถ iconic, honestly ๐Ÿ‘‘


Version 2.5.28 (from cvs), dated 2009-03-22, is the FvwmPerl(1) era ๐ŸŒธ thanks for reading, bestie, you're literally the best ๐Ÿ’–โœจ