FVWMPERL(1)   FVWMPERL(1)

FvwmPerl - دست‌ورز و پیش‌پردازنده perl برای fvwm

برای عملکرد عادی، FvwmPerl باید توسط fvwm (1) اجرا شود.

برای اجرای این ماژول، دستور Module FvwmPerl [params] را در فایل پیکربندی fvwm قرار دهید تا ارسال دستورات به FvwmPerl آغاز شود.

هدف این ماژول، گسترش دستورات fvwm با قدرت اسکریپت‌نویسی perl است. این ماژول امکان جاسازی عبارات perl در فایل‌های پیکربندی fvwm و ساخت دستورات fvwm را فراهم می‌آورد.

اگر می‌خواهید نمونه یکتا و ماندگار FvwmPerl را فراخوانی کنید، پیشنهاد می‌شود این کار را از طریق StartFunction انجام دهید. فراخوانی آن از ابتدا نیز امکان‌پذیر است، اما مسائلی به همراه دارد که در اینجا مطرح نشده است.

AddToFunc StartFunction I Module FvwmPerl

چندین سوئیچ خط فرمان وجود دارد:

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

سوئیچ‌های طولانی را می‌توان به سوئیچ‌های کوتاه تک‌حرفی خلاصه کرد.

-e|--eval line

ارزیابی کد perl داده‌شده

-l|--load file

ارزیابی کد perl در فایل داده‌شده

-p|--preprocess [ file ]

پیش‌پردازش فایل پیکربندی fvwm داده‌شده

۵ گزینه زیر تنها همراه با گزینه --preprocess معتبر هستند.

-c|--cmd line

یک دستور fvwm برای پیش‌پردازش به‌جای فایل.

-q|--quote char

تغییر نقل‌قول پیش‌فرض '%'.

-w|--winid wid

تنظیم صریح بافت پنجره (باید با رقم آغاز شود، می‌تواند در قالب هشت‌هشتی یا شانزده‌شانزدهی باشد؛ این شناسه پنجره در صورت وجود، بافت پنجره ضمنی را بازنویسی می‌کند).

--nosend

عدم ارسال فایل پیش‌پردازش‌شده به fvwm جهت Read کردن؛ حالت پیش‌فرض ارسال است. برای پیش‌پردازش فایل‌های پیکربندی غیر fvwm مفید است.

--noremove

عدم حذف فایل پیش‌پردازش‌شده پس از ارسال آن به fvwm جهت Read کردن؛ حالت پیش‌فرض حذف است. برای اشکال‌زدایی مفید است.

-x|--export [names]

تعریف توابع میانبر fvwm (به‌طور پیش‌فرض، دو تابع به نام‌های Eval و .). این گزینه مستلزم --stay است.

-s|--stay

ادامه اجرا پس از پردازش --eval، --load یا --preprocess. به‌طور پیش‌فرض، ماژول در این حالت ماندگار نیست؛ یعنی --nostay فرض می‌شود.

--nolock

هنگامی که یکی از ۳ گزینه عملیاتی مشخص شده باشد، این گزینه باعث باز شدن فوری قفل fvwm می‌شود. به‌طور پیش‌فرض، عملیات درخواستی به‌صورت همگام اجرا می‌شود؛ این موضوع تنها زمانی تفاوت ایجاد می‌کند که به این صورت فراخوانی شود:
ModuleSynchronous FvwmPerl --preprocess someconfig.ppp

اگر --nolock در اینجا اضافه شود، ModuleSynchronous بلافاصله بازمی‌گردد. توجه داشته باشید که Module بدون توجه به این گزینه فوراً بازمی‌گردد.

نام‌های مستعار (aliasها) این امکان را می‌دهند که چندین فراخوانی از ماژول داشته باشید و با هر فراخوانی به‌طور جداگانه کار کنید؛ این یک نمونه است:

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

یکی از راهکارهای مؤثر پیش‌پردازش، ارسال کل پیکربندی fvwm به همراه کد perl جاسازی‌شده به FvwmPerl --preprocess است. رویکرد جایگزین دیگر، نوشتن یک اسکریپت perl است که دستورات fvwm را تولید کرده و آن‌ها را برای اجرا ارسال می‌کند؛ این اسکریپت را می‌توان با استفاده از FvwmPerl --load بارگذاری کرد. با این حال، راهکارهای بینابینی نیز وجود دارند که تنها خطوط پیکربندی مجزا را پیش‌پردازش می‌کنند (یا متناوباً، دستورات perl مجزایی را اجرا می‌کنند که دستورات fvwm را تولید می‌نمایند).

قطعه‌کد زیر، قابلیت محاسبات ریاضی و اسکریپت‌نویسی رشته‌ای را به خطوط خاصی که به آن نیاز دارند می‌افزاید. برای استفاده از این قابلیت، بهتر است FvwmPerl را به عنوان نخستین دستور خود اجرا کنید تا بتوان از دیگر دستورات خواست که پیش‌پردازش شوند.

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"); ""}%

چندین اقدام (action) وجود دارد که FvwmPerl می‌تواند انجام دهد:

eval perl-code

یک خط از کد perl را ارزیابی می‌کند. تابع ویژه cmd(command*)* می‌تواند در کد perl برای پس فرستادن دستورات به fvwm استفاده شود. اگر کد perl حاوی خطا باشد، در جریان خطای استاندارد چاپ شده و سرآیند [FvwmPerl][eval]: به ابتدای آن افزوده می‌شود.

load file-name

یک فایل حاوی کد perl را بارگذاری می‌کند. اگر مسیر فایل به‌طور کامل مشخص نشده باشد، در دایرکتوری کاربر $FVWM_USERDIR (معمولاً ~/.fvwm) و دایرکتوری داده‌های سراسری سیستم $FVWM_DATADIR جستجو می‌شود. تابع ویژه cmd(command*)* می‌تواند در کد perl برای پس فرستادن دستورات به fvwm استفاده شود. اگر کد perl حاوی خطا باشد، در جریان خطای استاندارد چاپ شده و سرآیند [FvwmPerl][load]: به ابتدای آن افزوده می‌گردد.

preprocess [-q|--quote char] [-c|--cmd] [line | file]

فایل پیکربندی fvwm (file) یا (در صورت مشخص شدن --cmd) خط پیکربندی (line) را پیش‌پردازش می‌کند. این فایل حاوی خطوط دست‌نخورده (معمولاً دستورات fvwm) و کدهای perl با قالب‌بندی ویژه است که پردازش و جایگزین می‌شوند. متنی که در میان جداکننده‌های %\{ ... }% قرار گیرد، که می‌تواند از هر کجای خط آغاز شده و در هر جایی از همان خط یا خطی دیگر پایان یابد، کد perl است. پارامتر quote جداکننده‌های کد perl را تغییر می‌دهد. اگر یک نویسه تکی داده شود، مانند '@'، جداکننده‌ها @\{ ... }@ خواهند بود. اگر نقل‌قول داده‌شده ۲ نویسه باشد، مانند <>، نقل‌قول‌ها <\{ ... }> خواهند بود. کد perl با نتیجه ارزیابی آن جایگزین می‌شود؛ یعنی %\{$a = c; +$a}% با d جایگزین می‌شود. این ارزیابی برخلاف *eval* و *load* ذیل بسته PreprocessNamespace و بدون _use strict_ انجام می‌شود، بنابراین در استفاده از هر نام متغیری بدون ترس از تداخل آزاد هستید. فقط از متغیرهای مقداردهی‌نشده به معنای undef یا فهرست خالی استفاده نکنید (زیرا ممکن است در واقع توسط اقدام پیش‌پردازش قبلی مقداردهی شده باشند)، و در صورت نیاز پاک‌سازی انجام دهید. متغیرها و توابع بسته _main_ همچنان در دسترس هستند، مانند ::_cmd()_ یا ::_skip()_، اما دسترسی به آن‌ها حین پیش‌پردازش ایده مناسبی نیست. تابع ویژه‌ای به نام *include*(_file_) وجود دارد که یک فایل را بارگذاری کرده، آن را پیش‌پردازش می‌کند و نتیجه پیش‌پردازش‌شده را برمی‌گرداند. از بازگشت (تکرار بازگشتی) پرهیز کنید. اگر هر کد perl جاسازی‌شده‌ای حاوی خطا باشد، در جریان خطای استاندارد چاپ شده و سرآیند _[FvwmPerl][preprocess]:_ به ابتدای آن افزوده می‌شود. نتیجه جایگزینی در این حالت خالی است. متغیرهای زیر می‌توانند در کد perl استفاده شوند: `$USER+, `$DISPLAY, $WIDTH, $HEIGHT, $FVWM_VERSION, $FVWM_MODULEDIR, $FVWM_DATADIR, $FVWM_USERDIR. دستورالعمل‌های خط‌محور زیر هنگام پیش‌پردازش شناسایی می‌شوند. آن‌ها پس از جایگزین شدن کد perl (در صورت وجود) پردازش می‌شوند.

%Repeat count

باعث تکرار خطوط بعدی به تعداد count بار می‌شود.

%ModuleConfig module-name [ destroy ]

باعث می‌شود خطوط بعدی به عنوان پیکربندی ماژول مشخص‌شده تفسیر شوند. اگر destroy تعیین شود، پیکربندی قبلی ماژول ابتدا از بین می‌رود.

%Prefix prefix

عبارت نقل‌قول‌شده prefix را به عنوان پیشوند به ابتدای خطوط بعدی می‌افزاید.

%End any-optional-comment

به هر یک از دستورالعمل‌های شرح‌داده‌شده در بالا پایان می‌دهد؛ می‌تواند به‌صورت تو در تو باشد.
%Prefix "AddToFunc SwitchToWindow I"
    Iconify off
    WindowShade off
    Raise
    WarpToWindow 50 50
%End
%ModuleConfig FvwmPager destroy
    Colorset 0
    Font lucidasans-10
    DeskTopScale 28
    MiniIcons
%End ModuleConfig FvwmPager
%Prefix "All (MyWindowToAnimate) ResizeMove "
100 100 %{($WIDTH - 100) / 2}% %{($HEIGHT - 100) / 2}%
%Repeat %{$count}%
br w+2c w+2c w-1c w-1c
%End
%Repeat %{$count}%
br w-2c w-2c w+1c w+1c
%End
%End Prefix

export [func-names]

تعریف توابع میان‌بری را به fvwm ارسال می‌کند که به فعال‌سازی اقدامات مختلف ماژول کمک می‌کنند (یعنی eval، load و preprocess).

نام‌های توابع (func-names) می‌توانند با کاما و/یا فاصله‌های خالی از هم جدا شوند. به‌طور پیش‌فرض، دو تابع Eval و . در نظر گرفته می‌شوند.

اقدام واقعی تعریف‌شده در یک تابع، در صورت امکان از نام تابع حدس زده می‌شود، که در آن نام تابع . برای اقدام preprocess رزرو شده است.

برای نمونه، هر یک از این دو دستور fvwm:

SendToModule MyPerl export PerlEval,PP
FvwmPerl --export PerlEval,PPMyPerl
دو تابع میان‌بر زیر را تعریف کنید:
DestroyFunc PerlEval
AddToFunc I SendToModule MyPerl eval $*
DestroyFunc PP
AddToFunc I SendToModule MyPerl preprocessc-c $*

این ۴ اقدام را می‌توان به یکی از ۳ روش درخواست کرد: ۱) در خط فرمان هنگامی که FvwmPerl فراخوانی می‌شود (در این حالت FvwmPerl کوتاه‌مدت خواهد بود مگر اینکه --stay یا --export نیز داده شده باشد)، ۲) با ارسال پیام مربوطه در پیکربندی fvwm با استفاده از SendToModule، ۳) با فراخوانی تابع perl متناظر در کد perl.

چندین تابع وجود دارد که کد perl می‌تواند آن‌ها را فراخوانی کند:

cmd($fvwm_command)

در حالت eval یا load - رشتهٔ $fvwm_command را به fvwm بازمی‌گرداند. در حالت preprocess - رشتهٔ $fvwm_command را به خروجی کد perl جاسازی‌شده ضمیمه می‌کند.

do_eval($perl_code)

این تابع معادل قابلیت eval بر روی رشتهٔ `$perl_code` است که در بالا توضیح داده شد.

load($filename)

این تابع معادل قابلیت load بر روی فایل $filename است که در بالا توضیح داده شد.

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

این تابع معادل قابلیت preprocess با پارامترهای داده‌شده و فایل $filename است که در بالا توضیح داده شد.

export($func_names, [$do_unexport])

این تابع معادل قابلیت export با $func_names داده‌شده است که در بالا توضیح داده شد. در صورتی که پارامتر دوم درست (true) باشد، می‌تواند نام‌های توابع را unexport نیز بکند. نام‌های توابع باید با کاما یا/و فاصله از یکدیگر جدا شوند. اگر `$func_names` خالی باشد، توابع Eval و . در نظر گرفته می‌شوند.

stop()

ماژول را خاتمه می‌دهد.

skip()

از بقیهٔ کد بازخوانی رویداد (callback) صرف‌نظر می‌کند، یعنی ماژول برای گوش دادن به رویدادهای جدید ماژول بازمی‌گردد.

unlock()

ناهمگام‌سازی بازخوانی رویداد از fvwm. این ویژگی ممکن است برای جلوگیری از بن‌بست‌ها مفید باشد، به این صورت که معمولاً fvwm در صورتی که بازخوانی رویداد در ModuleTimeout ثانیه به پایان نرسد، ماژول غیرپاسخگو را خاتمه می‌دهد (kill می‌کند). این دستور از این کار جلوگیری می‌کند. این مثال باعث می‌شود که FvwmPerl اجرای خود را به مدت یک دقیقه معلق کند: SendModule FvwmPerl eval unlock(); sleep(60); با این حال، اطمینان حاصل کنید که به هیچ وجه پیام جدیدی توسط fvwm در زمان مشغول بودن ماژول ارسال نشود و fvwm برای مدت طولانی روی این پیام جدید قفل نماند. در صورتی که به عملیات‌های طولانی‌مدت نیاز دارید، راهکار detach را نیز ببینید.

detach()

بقیهٔ کد بازخوانی رویداد را از فرایند اصلی انشعاب داده (fork کرده) و جدا می‌کند. این کار ممکن است برای جلوگیری از متوقف شدن ماژول در حالتی که بازخوانی رویداد آن زمان زیادی می‌برد مفید باشد و کار در فرایند فرزند جداشده انجام شود. فرزند جداشده ممکن است همچنان بتواند دستوراتی را به fvwm ارسال کند (به این موضوع تکیه نکنید)، اما مسلماً رویدادها را دریافت نخواهد کرد و بلافاصله پس از اتمام اجرای بازخوانی خاتمه می‌یابد. در صورت استفاده از detach()، بهتر است تنها از طریق یک فرایند (فرایند اصلی یا فرزند جداشده) به fvwm دستور ارسال کنید؛ اقدام به شکل دیگر اغلب باعث بروز تداخل می‌شود.

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

یک پنجرهٔ محاوره‌ای با پیام مشخص‌شده را با استفاده از هر ابزار X موجود در سیستم نمایش می‌دهد. برای اطلاعات بیشتر به FVWM::Module::Toolkit::*show_message* مراجعه کنید.

چندین متغیر سراسری در فضای‌نام main وجود دارند که ممکن است در کد perl استفاده شوند:

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

همگی آن‌ها با مقدار خالی مقداردهی اولیه می‌شوند و می‌توانند برای ذخیره وضعیت میان فراخوانی‌های گوناگون به اکشن‌های FvwmPerl (eval و load) مورد استفاده قرار گیرند.

اگر به نام‌های متغیر خواناتری نیاز دارید، یا عبارت no strict 'vars'; را در آغاز هر کد perl بنویسید یا برای این کار از یک هش (hash) استفاده کنید، مانند:

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

یا از یک نام پکیج استفاده کنید، مانند:

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

ممکن است یک گزینه پیکربندی برای فعال یا غیرفعال کردن strictness وجود داشته باشد.

FvwmPerl می‌تواند با استفاده از دستور fvwm به نام SendToModule پیام‌ها را دریافت کند. نام‌ها، معانی و پارامترهای پیام‌ها همانند اکشن‌های متناظر هستند که در بالا توصیف شدند.

علاوه بر این، پیام stop موجب خروج ماژول می‌شود.

پیام unexport [func-names] اثر export را که در بخش ACTIONS توصیف شد خنثی می‌کند.

پیام dump محتوای متغیرهای تغییریافته را دامپ (تخلیه) می‌کند (هنوز پیاده‌سازی نشده است).

یک آزمایش ساده:

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
SendToModulecFvwmPerl unexport PerlEval,PerlLoad,PerlPP
SendToModule FvwmPerl stop

مثال زیر پس‌زمینه‌های root را در fvwmrc مدیریت می‌کند. همه این دستورها را می‌توان به 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))])

دستور SendToModule درست مانند هر دستور دیگر fvwm، چندین متغیر با پیشوند علامت دلار را بسط می‌دهد. این مسئله ممکن است با علامت‌های دلار مورد استفاده در perl تداخل داشته باشد. می‌توانید با قرار دادن یک خط پیوند (dash) پیش از SendToModule از این تداخل جلوگیری کنید. در هر جفت زیر، این ۲ خط معادل یکدیگرند:

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}%

راهکار دیگر برای اجتناب از گریزدهی نمادهای خاص مانند دلار و بک‌اسلش، ایجاد یک فایل perl در ~/.fvwm و سپس بارگذاری آن است:

SendToModule FvwmPerl load build-menus.fpl

اگر نیاز دارید دستوری را که با خط پیوند آغاز می‌شود پیش‌پردازش کنید، باید پیش از آن از «--» استفاده نمایید:

# 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"}%"

مجدداً، پیشنهاد می‌شود دستور(ها)ی خود را در یک فایل قرار داده و در عوض آن فایل را پیش‌پردازش کنید.

برنامهٔ FvwmPerl به دلیل این‌که با perl نوشته شده و با perl سر و کار دارد، از این شعار معروف perl پیروی می‌کند: «بیش از یک راه برای انجام آن وجود دارد، بنابراین انتخاب با شماست.»

در ادامه جفت‌های معادل دیگری از خطوط آورده شده است:

Module FvwmPerl --load "my.fpl" --stay
Module FvwmPerl -e load("my.fpl") -s
SendToModule FvwmPerl preprocess --quote @ my.pp
SendToModule FvwmPerl eval preprocess(\{quote => @}, "my.ppp");

هشدار: شما می‌توانید با ارزیابی کد مناسب در perl بر نحوهٔ کارکرد FvwmPerl اثر بگذارید؛ این موضوع یک قابلیت تلقی می‌شود، نه یک باگ. اما لطفاً این کار را انجام ندهید، بلکه ماژول fvwm اختصاصی خود را با perl بنویسید.

صفحهٔ راهنمای fvwm (1) تمامی دستورهای موجود را شرح می‌دهد.

اساساً، در کد perl خود می‌توانید از هر تابع یا متد کلاسی از کتابخانهٔ perl که به همراه fvwm نصب شده است استفاده کنید؛ به صفحات راهنمای بسته‌های perl شامل General::FileSystem، General::Parse و FVWM::Module مراجعه کنید..SH "نویسنده (AUTHOR)"

Mikhael Goikhman <migo@homemail.com>.

2026-06-28