Professional Documents
Culture Documents
1. FVWM 到哪里下载?有问题到哪里问?
2. 谁需要 FVWM?
如果你喜欢随意的控制自己窗口,让它们都乖乖听话,而
不是老是跳出来挡在你面前。你喜欢随意定制自己窗口样
式,喜欢快速高效的控制窗口,喜欢节省资源,…… 总
之,你是一个挑剔的人。那么 FVWM 就是你最终的选择。
FVWM 的用户包括很多超级大拿。你猜下面这个屏幕抓图
是谁的 FVWM? (点击可以放大)
3. 我与 FVWM 的故事
FVWM 的缺省配置是非常简陋的。当我第一次看到它时,
“天哪!世界上还有这么难看的窗口啊!”我立即选择了
"quit"。然后我选择了 KDE 和 Gnome。
4. FVWM 是什么样子?
这个问题是永远不会有答案的。问这个问题就像在问:
“Xwindow 是什么样子的?”也许勉强可以接受的回答是:
“你想让它是什么样子,它就会成为什么样子。”
但是一旦有了配置文件,FVWM 就会变得威力无比,简单的
配置文件可以实现基本的功能,复杂的配置文件甚至可以
模拟很多其它 WM 甚至 Windows XP。下面就是一个模拟
Windows XP 的例子,点击可以放大。很漂亮吧?什么时
候 Windows XP 也能这么漂亮就好了 :)
下面是一个模拟 CDE 的 dtwm 的例子:
以后如果有人告诉你:“FVWM 是那个样子。”你就可以对
他说:“FVWM 不一定是那个样子。” :)
你可以在 http://www.fvwm.org/screenshots/看到很多漂亮
的配置。
5. 配置文件和它的位置
配置文件有点像一个脚本语言。不要怕,这种脚本语言比
起 Perl, awk 简单多了。你不需要学会编程。配置文件是
在 FVWM 启动时读入并被 FVWM 执行的,你也可以在 FVWM
正在运行的时候与它“对话”,即时执行命令和修改界面
风格。
现在我们就来分析一下这个简单的配置文件里到底在说些
什么。
6. 什么是 FVWM 命令
一个配置文件里基本上是一些命令,与其它 WM 不同的是,
FVWM 并不区分样式命令和动作命令,你可以几乎在任何情
况下使用任何命令。比如命令:
Mouse 1 A CSM Style gvim TitleAtBottom
7. 怎样实验新的 FVWM 命令
实验一个命令的作用不需要重新启动 FVWM,你可以先在
.fvwm2rc 里这样定义:
8. 常用命令
FVWM 可以有很多个虚拟桌面(desk)(几乎无穷多!),每个
虚拟桌面可以被分成很多个页("page")。这些 page 相当于
把你的屏幕扩大了很多倍。这一行就是设定每个 desk 包含
多少 page.
ImagePath +:/usr/share/icons:/usr/share/pixmaps:
$HOME/.fvwm/icons
就举这些吧……我只是举出了我有时会用到的,其实还有
很多很多,你看看 FVWM 的 manpage 就知道了。
23.窗口上下文
24.鼠标和键盘
FVWM 几乎可以以无穷的方式组合,来进行鼠标和键盘的操
作。你还可以加入窗口上下文来进行更方便的动作。
键盘操作的定义:
鼠标操作的定义:
Modifiers 是鼠标操作时同时的键盘控制键。M 表示
"Meta",在 PC 上就是 Alt,S: shift, C: ctrl. 还有 A: any,
N: none. 也可以组合,比如"MS" 表示同时按下 Alt-Shift.
现在我们分析一下下面这个定义:
Mouse 3 W SC CloseOrNot
这个定义是说,在窗口上点击鼠标右键,并且先按下
Shift-Ctrl,那么调用 CloseOrNot 这个 FVWM 函数。这个
函数会作用与当前鼠标所在的上下文,也就是一个窗口。
函数是这样定义的:
31.函数
DestroyFunc CloseOrNot
AddToFunc CloseOrNot
+ C Silent Close
+ M Nop
你可以把一系列的操作有条件的加入到一个叫做“函数”
的结构里,以后这个函数就可以像命令一样被使用了。
• 如果是一个鼠标点击(C), 那么关闭这个窗口(Close),
但是如果现在不是在窗口上下文,也就是说,函数
调用的时候没有一个确定的目标,那么不进行操作,
而不是出现一个"+"字瞄准器让用户选择窗口。 这
就是 "Silent" 的含义。
32.如果鼠标点下去之后移动了,也就是“拖动”(M),那么不
进行操作。
33.启动函数和退出函数
DestroyFunc InitFunction
AddToFunc InitFunction
+ I Exec exec xscreensaver -no-splash
DestroyFunc ExitFunction
AddToFunc ExitFunction
+ I All (xdaliclock) Close
+ I All (xscreensaver) Close
+ I All (xsim) Close
退出和重起时,我特意关闭了那几个启动时打开的程序,
因为如果不关闭他们,像 xwin32, Exceed 这样的 Windows
X server 不会 Reset.
34.窗口样式
Style 语句用于设定窗口的样式。你可以随心所欲的让不
同的窗口有不同的样式。语法为:
options 是你想让满足条件的窗口以什么样的方式存在。
options 的种类非常之多。比如:BorderWidth,
HandleWidth, FocusFollowsMouse, TileCascadePlacement,
... 它们有的需要参数,比如 BorderWidth 7, 指定边框宽
度为 7 个像素。有些不需要参数,比如
FocusFollowsMouse/ SloppyFocus/ NeverFocus/
ClickToFocus 指明了几种互相排斥的键盘聚焦方式。 先
举几个例子,这些都是 system.fvwm2rc 里的内容:
Style * FocusFollowsMouse
Style * TileCascadePlacement
Style "Fvwm*" NoTitle, Sticky, WindowListSkip
Style "Fvwm*" BorderWidth 2, CirculateSkipIcon, CirculateSkip
Style "FvwmPager" StaysOnTop
Style "FvwmBanner" StaysOnTop
Style "FvwmButtons" Icon toolbox.xpm, ClickToFocus
开头的两行说明所有窗口,都是鼠标移进去的时候得到键
盘聚焦,鼠标移出来就失去聚焦(FocusFollowsMouse),窗
口出现的时候,先试图找一个可以放下它而不挡住其它窗
口的地方,如果不行再采用层叠放置的方式
(TileCascadePlacement)。
总的说来,options 指出了控制窗口的基本样式和政策,
而不包括窗口各个部件具体的样式,它包括以下几个方面
内容:
• 窗口聚焦方式。是跟随鼠标(FocusFollowsMouse),还
是需要点击才聚焦(ClickToFocus)...
35.窗口标题栏。是否给窗口加上标题拦?如果加上,是放在
左边,上边,还是下边?注意这里也不是设定具体标题样
式的地方,参看 TitleStyle.
36.窗口应该显示哪些按钮。FVWM 可以为每个窗口设定最多
10 个按钮,但是你通常用不到 10 个,这样你可以设定对于
某一个程序那些按钮应该出现。注意这里也不是设定按钮
样式的地方,参看 ButtonStyle.
37.窗口边框样式。边框宽度,handle(就是边框角上那个用来
resize 的东东)的宽度,边框被鼠标按住的时候是否陷下
去?...
38.窗口图标。用那个图标作为窗口 iconify 时候的图标?
39.窗口最大化,移动,改变大小操作时的样式。是显示窗口
内容还是只显示一个“橡皮框”?还是让尺寸小于某个值
的窗口才在拖动时显示内容?...
40.窗口放置策略。窗口出现的时候,是层叠放置,最小遮挡
放置,还是……?
41.是否允许程序自己放置自己?这是一个政策问题,有些窗
口程序启动时会自己选择一个位置出现,但是你可能会发
现你不喜欢它那样做,你可以设定 NoPPosition, 不允许那
个程序自作聪明。
42.对瞬时窗口(transient window)的策略。transient window
是指类似弹出菜单,对话框之类的窗口。当它们出现的时
候,你是否想给它们也加上标准的边框?
43.高级特性。还有很多很多选项比如是否允许窗口 backing
store,这些如果你还不理解现在暂时不用管它。
以上每项都包含许许多多可以设定的东西。具体还是请参
考 fvwm 的 manpage。
44.菜单
一个窗口管理器怎么能没有菜单?FVWM 的菜单是可以随意
自己定义的,它在任何时候出现在你想让它出现的任何地
方。一个菜单首先有一个定义,然后有 一个激发这个菜
单的条件,菜单的样式也可以随意定制。如果使用
PipeRead 命令和一些 shell 命令组合,你就可以用菜单
的方式遍历你的文件目录树,成为一个“菜单式 file
manager”。
• 菜单的定义
是这样定义的
DestroyMenu RootMenu
AddToMenu RootMenu "Root Menu" Title
+ "&xterm%mini.display.xpm%" Exec
exec xterm
+ "&Rxvt%mini.monitor.xpm%" Exec
exec rxvt
+ "&Big Rxvt" Exec exec rxvt
-geometry 78x43
+ "" Nop
+ "&Programs" Popup ProgramsMenu
+ "&Utilities" Popup Utilities
+ "" Nop
+ "Re&fresh Screen" Refresh
+ "Re&capture Screen" Recapture
+ "" Nop
+ "&Lock" Exec exec
xscreensaver-command -lock
+ "&Exit Fvwm%mini.exit.xpm%" Popup
Quit-Verify
除了第一行,后面的行都以一个+号开头,这说明以
下是上一个命令的继续。这样我们定义了一个菜单,
它的名字叫 "RootMenu", 它有一个标题叫"Root Menu",
里面有一些程序。当我们选中 "XTerm" 时,会使用
FVWM 的 Exec 命令启动一个 shell,这个 shell 马上
会执行"exec xterm", 也就是启动一个 xterm。空字
串"" 表示在菜单里画一条分隔线。Popup 可以弹出
子菜单,子菜单也是用同样的方法定义的。"&"后面
的那个字母会变成键盘的热键而被加上下划
线,"%"括起来的是图标文件的名字,你需要 设置
ImagePath 指向图标文件所在的目录。你还可以在菜
单里加入侧面图标,等等等等。
• 菜单的消灭
DestroyMenu RootMenu
光是定义了一个菜单你是不能马上使用它的。这个
菜单在什么情况下出现?这个问题是需要你自己来
决定,这也是显示 FVWM 的完全可定制性的地方。比
如,我们可以这样定义一个激活菜单的方式:
这句话的意思是:“当鼠标(Mouse)左键(1)在根窗口
(R)上点击,同时有任何控制键(A)按下,这个时候显
示叫做 RootMenu 的菜单。”
但是有时候我们不容易在屏幕上找到一个可以看到
根窗口的地方来点击鼠标。我们可以再加一个定义:
• 菜单的样式
MenuStyle * MWM
MenuStyle * PopupDelayed, PopupDelay 160, Animation, TitleWarp
MenuStyle * Foreground gold, Background gray40
MenuStyle * ActiveFore White
MenuStyle * Font -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*
MenuStyle * MenuFace VGradient 64 darkgray MidnightBlue
• 动态菜单定义
前面我们说过了,可以用 PipeRead 来构造一个动态
菜单。现在举一个简单的例子:
AddToMenu HomeDirMenu
PipeRead 'for i in $HOME/prog/*.c; \
do echo "+ $i Exec xterm -e vi $i"; done'
46.按钮
窗口的标题栏上都有一些按钮。那不是窗口程序自己的,
而是 WM 给它们加上的。
• 按钮编号
按钮是这样编号的:
左边是奇数右边是偶数, 外面的大中间的小。
• 按钮功能定义
下面看看按钮的功能是怎么定义的,在鼠标和键盘
一节我们已经知道怎么定义鼠标了,按钮的功能只
不过是把鼠标与按钮号码组合在一起。
比如我的窗口上一般有三个按钮, 都在右上角,注意
它们的编号:
6 4 2
他们的功能是这样定义的:
Mouse 1 4 A Iconify
Mouse 1 6 A Close
Mouse 3 2 A Maximize-Func2
DestroyFunc Maximize-Func2
AddToFunc Maximize-Func2 "M" Maximize 100 0
+ "C" Maximize 80 0
+ "D" Maximize 100 100
如果鼠标右键在“最大化”按钮上点击(C)那么高度
增长为屏幕的 80%, 宽度不变。如果按下鼠标右键后
有拖动(M), 那么高度增长为屏幕高度(100%), 宽度不
变。如果双击(D), 就是一般的最大化。
为什么是右键?因为我为左键在这个按钮上定义了
更高级的 stroke 来改变窗口大小。我们稍后介绍。
• 按钮样式
右边两个按钮的图案是系统缺省的,那个"X"形按钮
是下面第三句话画出来的。 这种绘图语句非常简单。
ButtonStyle 之后的数字是按钮编号,后面一个数子
表示一共有多少笔画。后面的 XxY@C 都是笔画的内
容,XxY 是坐标, 坐标都是用百分比表示的。@C 表
示颜色, C 是一个数字,0 表示阴影色,1 是高亮色,
2 是背景色,3 是前景色,4 是移动光标而不画线。
你可以画你自己的按钮,也可以去拿别人设计好的
来用。FVWM 的主页上有很多人提供这种按钮。
47.其它样式
48.条件命令
把所有图标化的窗口都移动到桌面右下角的那一页。
以后按 F5 就可以让当前聚焦窗口上面(North)那个窗口往
下长大,直到被当前窗口挡住去路。你有时候想在 VIM 里
抄 Acrobat Reader 里的内容,安排窗口大小的时候就可
以用这招。
49.手写操作 (Stroke)
• 让 FVWM 支持 Stroke
当然这些控制方式都是你自己决定的, 这一切只需要
在 .fvwm2rc 里加入一些 Stroke 语句. 因为太多了,
写在主配置文件影响编辑, 这些语句被我写到了另一
个文件里,然后在主文件用 Read 语句读入。你可
以在这里下载我的 fvwm.stroke 文件作为参考。
你还可以定义非常高级的操作,你甚至可以这样:
按住 ctrl, 用鼠标中键画出一条射线箭头指向的那
个窗口, 不论它在那个桌面,就会被吸过来,并且随
鼠标移动,你点击左键就可以放置它。
• 轨迹
1 2 3
4 5 6
7 8 9
轨迹也可以用你的小键盘上的数字键来确认。看看
你的小键盘:
7 8 9
4 5 6
1 2 3
• Stroke 项目的定义
比如:
Stroke 关键字之后跟上轨迹说明。轨迹是一系列数
字,如果数字前面有一个"N", 就表示我们采用小键盘
的布局,而不是电话拨号盘。你看我的那几个轨迹,
实际上是我们在写 "r" 字母的时候有可能出现的几
种情况。
比如,这个轨迹就是符合 "N7414589".
轨迹之后是鼠标按键号码。如果号码不是 0,那么一
旦识别到这个轨迹,就会马上执行操作。但是如果
号码是 0,那么说明这个定义不是在任何时候识别到
就马上进行的。而是当 StrokeFunc 命令被调用的时
候才进行。StrokeFunc 为你提供了更多的灵活性。
• StrokeFunc
现在看到了? 这就是我的最大化按钮上对鼠标左键的
绑定。DrawMotion 是 StrokeFunc 的一个可选参数,
它可以让轨迹在屏幕上被画出来,这样你可以清楚
的看到你到底写了什么。
#grow bidirectional
Stroke N25852 0 TSF2 N Maximize True 0 grow
Stroke N5852 0 TSF2 N Maximize True 0 grow
........
#reverse to unmaximized
Stroke N74123 0 TSF2 N Maximize False
我的鼠标左键按下“最大化”按钮之后可以进行绘
画,然后窗口会随着轨迹的不同而采取各种各样的
改变大小的行动!
我还有一个定义:
这样鼠标右键在窗口标题栏,边框,frame 上绘画
时也会触发 StrokeFunc 函数,达到跟左键在“最大
化”按钮上绘画同样的效果。发现了吧?StrokeFunc
为我省去了重复的轨迹定义,否则我需要为“左键+
最大化按钮”和“右键在边框”定义两套 stroke.
59.实例分析
我们来分析一种可能的执行情况:用鼠标左键按下
“最大化”按钮(2),然后向右画。就像这个样子:
当鼠标左键在“最大化”按钮(2)上按下之后,如果
没有键盘控制键按下(N),而那么根据"Mouse 1 2 N
StrokeFunc DrawMotion", FVWM 就会发现应该调用
StrokeFunc.
StrokeFunc 会马上记录鼠标按下的时候有哪些控制
键按下了,现在是没有控制键(N).
然后它发现鼠标随即向右画出了一条线,看看你的
小键盘,这是 N456。StrokeFunc 就会在已经定义的
Stroke 里去找,是否存在这样的一个定义,它的前
面部分是
它发现有一个
Stroke N456 0 TSF2 N Maximize True growright 0
注意控制键都是在动作开始时就已经记录下来了。
如果你在绘画的途中放开了或者按下了控制键是不
会改变识别的效果的。
• 怎样提高识别率
通常不要定义太复杂的轨迹,因为变化太多了就不
容易识别。左右晃一晃,上下摇一摇,转个圈儿,
……已经可以完成你很多任务了。
如果是复杂的 stroke, 比如写一个字母,你需要定
义很多相似的 stroke,否则有时不能匹配。如果你
不能确定会出现那些轨迹,你可以给 StrokeFunc 一
个参数,比如:
然后你在屏幕上多画几次你的那个字母,无论它是
否匹配一个定义,FVWM 会在启动它的那个终端输出
你画出的轨迹号码。那些就是你写这个字母时有可
能出现的轨迹,你把这些序列都加到你的配置文件,
这样就提高了识别率。
• 键盘触发 Stroke
stroke 也可以由键盘来触发。比如:
60.模块
• 你有没有发现。当你的鼠标移动到窗口后,如果它
被别的窗口挡住了,它并不会跑到上面来。如果你
想让它自动上来,你可以使用 FvwmAuto 模块来实
现一个简单的“自动提升”功能。我的
StartFunction 里有如下内容:
AddToFunc StartFunction
+ I Module FvwmAuto 500 Raise Nop
*FvwmAnimate: Delay 25
*FvwmAnimate: Effect Random
*FvwmAnimate: Width 3
既然 fvwm 有很多工作区。能不能有一个东西可以方便的
看到那些工作区上有哪些程序,而且可以方便的切换工作
区呢?FvwmPager 就是为这个目的设计的。 我的 Pager 是
这个样子:
FvwmPager 有很多可以设定的参数,现在你可以试试这个
简单的配置,这就是上面这个 pager 的配置。
*FvwmPager: Rows 4
*FvwmPager: Columns 1
*FvwmPagerBack #908090
*FvwmPagerFore #484048
*FvwmPager:Font -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*
*FvwmPagerHilight #cab3ca
*FvwmPagerLabel 0 Main
*FvwmPagerLabel 1 Internet
*FvwmPagerLabel 2 Program
*FvwmPagerLabel 3 Amusement
*FvwmPager:SmallFont -*-simsun-medium-r-*-*-12-*-*-*-*-*-*-*
*FvwmPagerBalloons All
*FvwmPagerBalloonBack Yellow
*FvwmPagerBalloonFore Black
*FvwmPager:BalloonFont -*-simsun-medium-r-*-*-14-*-*-*-*-*-
*-*
*FvwmPagerBalloonYOffset +2
*FvwmPagerBalloonBorderWidth 1
*FvwmPagerBalloonBorderColor Black
Module FvwmPager 0 3
70.FvwmButtons
这里是我的一个简单的配置:
*FvwmButtonsBack bisque3
*MainPanel: Geometry 80x18+40+4
*MainPanel: Back SeaGreen
*MainPanel: (Panel(down, indicator, delay 0, steps 1) \
PagerPanel "Module FvwmButtons PagerPanel")
*MainPanel: Font -*-simsun-medium-r-*-*-16-*-*-*-*-*-*-*
*PagerPanel: Geometry 80x352
*PagerPanel: (Swallow FvwmPager "Module FvwmPager 0 3")
*PagerPanel: Font -*-simsun-medium-r-*-*-16-*-*-*-*-*-*-*
来启动它. 它启动时是这个样子:
挂在屏幕左上偏右一点的地方,既没有挡住左边的按钮,
又不会挡住窗口的下拉菜单。点一下就会展开,展开以后
就是这个样子:
再点就会缩回去。
FvwmButtons 可以提供的功能远远不止这些。FvwmButtons
是一个非常强大的模块。你有兴趣可以看看它的 manpage.
71.FAQ
这一节来看看我遇到过的一些问题。
• FVWM 怎么锁定屏幕呢?
你又问到一个容易混淆的问题。锁定屏幕也不是 WM
必须有的功能。几乎所有 WM 都是调用另外一个程序,
比如 xscreensaver 来锁定屏幕和提供屏幕保护,然
后在它们的菜单里加入对 xscreensaver 配置程序
xscreensaver-demo 的调用。看起来好像是 WM 提供
了屏幕保护功能,让很多用户模糊了 WM 的职责。
FVWM 当然能显示汉字了,它是一个国际化的程序。
原因在于你没有设置好汉字字体。你可以在配置文
件里加入汉字字体的设定:
Style * Font -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*
simsun 是我机器上一种同时可以支持汉字和英语编
码的字体,如果你的字体只有汉字编码,那么你的
英文全部都会“乱码”,这时你需要在后面再加一
个英文字体。比如:
类似的,pager,windowlist 都有自己的字体设定,
你需要把它们都设置为你喜欢的中文字体。
• FVWM 有工具条吗?
另外,FvwmButtons 模块提供了更加复杂的功能。你
可以把很多小程序(xclock,biff...)和模块
(FvwmIconMan)嵌入到它里面。形成一个复杂的工具
条。 详情请 man FvwmButtons。你也可以使用 KDE
的 kicker 工具条和 Gnome 的 gnome-panel. 请看后
面。
能。把这行加入 .fvwm2rc:
Key Tab A M -
取消这个定义。
72.我不想要鼠标移动到窗口上就自动聚焦的方式怎么办?
• 我用 MouseFocus 方式,可是当我的一个窗口被
Lower 后,我只能把鼠标移到其它窗口再移回来才
能重新提升它。
Style * MouseFocusClickRaises
• 怎样才能使窗口获得焦点后自动提升?
AddToFunc StartFunction
+ I Module FvwmAuto 500 Raise Nop
把这行加到你的配置文件就行了:
把这行加到你的配置文件就行了:
Style "Display" RaiseTransient LowerTransient
StackTransientParent
Style "Gimp" RaiseTransient LowerTransient
StackTransientParent
• 屏幕保护出现时,XSIM 输入法的状态窗口为什么不
消失呢?
wa.override_redirect = False;
set_winattr(CWOverrideRedirect, &wa);
问题就已经解决了。
/*
XSetWindowAttributes wa;
wa.override_redirect = True;
set_winattr(CWOverrideRedirect, &wa);
*/
自己设置它的属性。我们可以给它边框,也可以不
给它边框。你可以把这些配置写到你的 .fvwm2rc 得
到一个比较好的效果。
Style "XSIM" Layer 7, NoTitle, HandleWidth 1, Sticky,
WindowListSkip
73.特种技巧
• 即时战略游戏式的控制窗口
很多即时战略游戏都可以对士兵等进行分组 比如选
定一组士兵后按 Ctrl-Alt-1,可以把一组士兵标记
为第 1 小分队 以后按 Ctrl-1 就可以让这些士兵待
命。
其实 FVWM 可以很容易把一些窗口当成士兵。只要把
这些行加入 .fvwm2rc
................
................
想到了吗?好了,来看看一个更超级的用法。在你
的 .fvwm2rc 加入这些:
Key 0 WI SC State 0
Key 1 WI SC State 1
Key 2 WI SC State 2
Key 3 WI SC State 3
Key 4 WI SC State 4
Key 5 WI SC State 5
Key 6 WI SC State 6
Key 7 WI SC State 7
Key 8 WI SC State 8
Key 9 WI SC State 9
Key a WI SC State 10
....
DestroyFunc GroupFunc
AddToFunc GroupFunc I Layer 1
+ I MoveToPage
+ I Iconify off
+ I Raise
以后按 Ctrl-Shift-n,就可以把当前聚焦窗口设置
为“第 n 组”(State n)。n 可以从 0 到 31。以后我
们可以按 Alt-n 来把第 n 组的窗口都移动到当前
page,全部 deiconify 并且提升--待命!
我的配置文件定义了很多奇怪的热键加鼠标的用法,还有
stroke。你肯定不希望马上拷贝到你的目录里使用,因为
你会不知道怎么用了 :)
[.fvwm2rc] [fvwm.strokes]
返回