FVWM 簡明使用指南

http://docs.huihoo.com/homepage/shredderyin/fvwm.html

 

FVWM簡明使用指南

Fvwm is a window manager for X11. It is designed to minimize memory consumption, provide a 3D look to window frames, and a virtual desktop.

— The FVWM(F? Virtual Window Manager) manual

在看這個文檔之前你最好對 Xwindow 的工作機制有一定了解。知道 X server 跟 WM 有什麼關係。你可以參考我的 Xwindow 網頁

FVWM 到哪裏下載?有問題到哪裏問?

先說正事吧。FVWM 的老巢在http://www.fvwm.org。那裏有所有源碼和各種按鈕,菜單樣式,圖標,聲音,抓圖,……下載。

另外,你可能想要FVWM支持鼠標動作。你可以在 http://www.etla.net/libstroke/ 得到 libstroke. 下載那個爲 FVWM 準備的版本,編譯後安裝,然後再編譯 FVWM,它一般就會找到 libstoke,從而加入 stroke 的功能。

FVWM 的問題最好到 FVWM 郵件列表討論,那裏的人們都很熱情。地址見 FVWM 的主頁。

誰需要 FVWM?

並不是任何人都會喜歡 FVWM。使用 FVWM 顯然不像用 KDE,Gnome 的桌面那麼簡單,你需要自己對它進行配置。它是一個老牌的,長久不衰的窗口管理器,它永遠以一個忠實的 Xwindow 窗口管理器的方式工作。使用 FVWM,你可以學到很多有關 Xwindow 的東西,你會很快的明白 Xwindow 的工作原理,見識到 Xwindow 的強大和靈活。

如果你喜歡隨意的控制自己窗口,讓它們都乖乖聽話,而不是老是跳出來擋在你面前。你喜歡隨意定製自己窗口樣式,喜歡快速高效的控制窗口,喜歡節省資源,…… 總之,你是一個挑剔的人。那麼 FVWM 就是你最終的選擇。

FVWM 的用戶包括很多超級大拿。你猜下面這個屏幕抓圖是誰的 FVWM? (點擊可以放大)

我與 FVWM 的故事

FVWM 的缺省配置是非常簡陋的。當我第一次看到它時,“天哪!世界上還有這麼難看的窗口啊!”我立即選擇了 "quit"。然後我選擇了 KDE 和 Gnome。

但是當我被 KDE,Gnome 華麗的難以忍受的不穩定性煩透了時候,當我快要放棄使用 Linux 和 Xwindow 的時候,我在 Knuth 的主頁上看到了他的 Linux 系統下的漂亮的 FVWM 抓圖。天哪!我忽略了世界上最強大的窗口管理器。它完全可以變得比任何其它窗口管理器漂亮,它讓我領悟到了 Xwindow 的魅力。它不但很強大,而且可以和 KDE, Gnome 裏的程序一起工作。

FVWM 是什麼樣子?

這個問題是永遠不會有答案的。問這個問題就像在問:“Xwindow 是什麼樣子的?”也許勉強可以接受的回答是:“你想讓它是什麼樣子,它就會成爲什麼樣子。”

FVWM 是一個完全可定製的窗口管理器。這是FVWM不同於很多其它WM的一個特點,它的一切行爲方式都是由一個配置文件: .fvwm2rc 決定的。沒有了這個配置文件,FVWM 就成了一個廢物: 鼠標和鍵盤幾乎不起任何作用,沒有菜單,沒有窗口邊框,沒有按鈕,甚至你根本不知道它其實正在運行!

但是一旦有了配置文件,FVWM就會變得威力無比,簡單的配置文件可以實現基本的功能,複雜的配置文件甚至可以模擬很多其它WM甚至 Windows XP。下面就是一個模擬 Windows XP 的例子,點擊可以放大。很漂亮吧?什麼時候 Windows XP 也能這麼漂亮就好了 :)

下面是一個模擬 CDE 的 dtwm 的例子:

以後如果有人告訴你:“FVWM是那個樣子。”你就可以對他說:“FVWM不一定是那個樣子。” :)

你可以在http://www.fvwm.org/screenshots/看到很多漂亮的配置。

配置文件和它的位置

配置文件叫做 ~/.fvwm/.fvwm2rc, 在你的用戶目錄下。

配置文件有點像一個腳本語言。不要怕,這種腳本語言比起 Perl, awk 簡單多了。你不需要學會編程。配置文件是在FVWM啓動時讀入並被FVWM執行的,你也可以在FVWM正在運行的時候與它“對話”,即時執行命令和修改界面風格。

寫配置文件,一個很好的出發點就是隨 FVWM 源碼發行的 system.fvwm2rc 文件。它的位置現在在源碼包的 sample.fvwmrc/system.fvwm2rc。你也可以在這裏下載一份 2.5.4 的system.fvwm2rc. 把它拷貝到你的 ~/.fvwm/ 目錄下面, 改名爲 .fvwm2rc. 作爲我們的起始點。

注意sample.fvwmrc/ 這個目錄下還有system.fvwm2rc-sample-95這樣的配置文件,它們可以模擬 Windows 95 的操作方式,但是這個配置文件太大了,不適合用來修改成爲自己的配置文件,你有興趣可以自己看看,然後把裏面某些你覺得很cool的東西貼到你的配置文件裏。

現在我們就來分析一下這個簡單的配置文件裏到底在說些什麼。

什麼是FVWM命令

一個配置文件裏基本上是一些命令,與其它WM不同的是,FVWM並不區分樣式命令和動作命令,你可以幾乎在任何情況下使用任何命令。比如命令:

Mouse 1 A CSM Style gvim TitleAtBottom

讓你在任何時候按住 Ctrl-Shift-Alt 再點擊鼠標左鍵(編號1),名叫gvim的窗口的標題欄就會跑到下面去。是不是很好玩?呵呵。這裏 "Style" 是一個樣式命令。

Mouse 2 A CSM All (rxvt) MoveToDesk 0

按住 Ctrl-Shift-Alt 再點擊鼠標左鍵中鍵(編號2),所有的 rxvt 都會被移動到當前的桌面. 這裏的 "All" 是一個可以附加條件和操作的條件動作命令,我們在後面會介紹。

怎樣實驗新的FVWM命令

實驗一個命令的作用不需要重新啓動FVWM,你可以先在 .fvwm2rc 裏這樣定義:

Key F3 A A Module FvwmConsole 

然後啓動fvwm, 這樣你在任何時候按下 <F3> 鍵,就會啓動一個叫做 FvwmConsole 的模塊,你可以在裏面輸入Fvwm命令,回車它們就會執行,並且立即生效。這是直接與FVWM對話的方法。當然如果你想得到下面這麼漂亮的 FvwmConsole, 還需要對 xterm/rxvt 的參數作一些設定。其實我的定義是:

Key F3 A A Module FvwmConsole -terminal rxvt -geometry 45x5-0+0 /
	-bg gold -fg midnightblue /
	-fn "-adobe-courier-medium-r-*-*-14-*-*-*-*-*-*-*"

常用命令

FVWM 可以有很多個虛擬桌面(desk)(幾乎無窮多!),每個虛擬桌面可以被分成很多個頁("page")。這些page相當於把你的屏幕擴大了很多倍。這一行就是設定每個desk包含多少page.

DeskTopSize 這類語句指定了整個FVWM的某種行爲方式,類似的語句還有很多。下面列舉一些,你第一次看本文可以草草略過這一節。

  • Read file. 插入另外一個文件file的內容。如果你會C語言,你就知道這個語句相當於 #include . 當你的配置文件在某一方面有很長內容時,比如我的配置文件裏有大量stroke,你就可以把這些都寫到另一個文件裏,這樣使主配置文件容易修改。
  • Exec app. 啓動一個shell,並且在裏面執行"app"命令。這時用菜單和按鈕來啓動程序時經常用到的命令。

    如果你要啓動一個X程序最好同時使用 exec, 比如

    Exec exec rxvt

    這樣shell會執行"exec rxvt", 用rxvt替代自己的正文段,這樣纔不會出現很多shell在那裏等待X程序返回。

  • Module FvwmXxx. 啓動一個叫做 FvwmXxx 的模塊。一個模塊是一個程序,它直接通過管道與Fvwm通信,所以必須從Fvwm fork() 出來,而不能從一個 xterm 獨立啓動。模塊可以無限制的擴展Fvwm的功能,只要 Xlib 允許。
  • ImagePath path. 指定一個路徑,在配置文件裏要用到的圖標等文件就會到這個路徑裏去尋找。比如:
    ImagePath +:/usr/share/icons:/usr/share/pixmaps:
    $HOME/.fvwm/icons
    
    加號是表示以前定義過的那個 ImagePath. FVWM 可以使用 .xbm, .xpm 和 .png 格式的圖標。
  • Move, Raise, Lower, Resize, ... 這些都是常用的操縱窗口的命令。
  • Close, Delete, Destroy, Iconify, Maximize, WindowShade. 關閉窗口,圖標化窗口,最大化窗口,shade 化窗口. 你會發現Xwindow關閉窗口的方式有很多種,其中 Close 是最文明的一種,這會發給窗口一個消息讓它收拾乾淨然後退出。Destroy 是立即殺死這個窗口,跟 xkill 的功能一樣。Delete介於兩者之間,先禮後兵,如果窗口不知道怎麼收拾乾淨,那麼就強行殺死它。
  • OpaqueMoveSize x. 如果一個窗口移動時顯示內容,那麼它必需佔屏幕面積的 x%.
  • MoveToDesk, MoveToPage. 可以把任何窗口移動到指定的桌面和頁面。
  • SnapAttraction. 設定在什麼距離以內,滿足什麼條件的窗口就被吸附在一起。biaji~~~~~
  • WarpToWindow x[p] y[p]. 讓鼠標移動到窗口範圍以內。x,y是在窗口內的座標,用百分比表示。後面如果有後綴"p", 就用像素來表示。
  • IgnoreModifiers. 你可以忽略某些鍵盤控制鍵。這將影響到你的鼠標和鍵盤熱鍵定義。詳細情況見鼠標和鍵盤一節。
  • DesktopName desk name. 定義第desk號桌面的名字叫 name.
  • Scroll. 移動你在桌面上的 viewport, 這樣你可以把桌面當成一個整體來瀏覽。看到很大的範圍。
  • Nop. 不操作,在有些時候需要用它來佔位,下面我們會遇到這樣的例子。
  • PipeRead. 從一個外部命令得到輸入。這可以用來根據你的系統構造許多非常高級的控制方式。其中一種叫做“菜單式文件管理器”。我們在菜單一節會遇到這個用法。
  • SetEnv. 設置FVWM的環境變量。

就舉這些吧……我只是舉出了我有時會用到的,其實還有很多很多,你看看 FVWM 的manpage就知道了。

窗口上下文

Move, Close, WarpToWindow ...這些命令如何知道作用於那個窗口呢?如果你因爲點擊了窗口上的按鈕,邊框,……而激發了這些命令,那麼這些命令就會作用於這個窗口。或者你也可以用條件選擇命令確定一個或者一批窗口進行操作,見條件命令。否則,這些命令不知道應該作用於哪個窗口,比如你在 FvwmConsole 裏鍵入 "Close", Close 命令就沒有窗口上下文,它缺省會出現一個“+”狀的選擇器讓你選擇一個窗口。如果你不希望命令在沒有窗口上下文的時候自動讓你選擇一個窗口,那麼你可以在命令前面加上 "Silent".

鼠標和鍵盤

FVWM幾乎可以以無窮的方式組合,來進行鼠標和鍵盤的操作。你還可以加入窗口上下文來進行更方便的動作。

鍵盤操作的定義:

Key Keyname Context Modifiers Function

它表示:在名叫 Keyname 的鍵在 Context 上下文按下時,如果控制鍵 Modifiers 組合按下,那麼執行 Function. 鍵盤操作後面的部分跟鼠標一樣的含義,我們下面只用鼠標操作來一起說明這些命令的用途。

鼠標操作的定義:

Mouse Button Context Modifiers Function

它表示:在鼠標編號爲 Button 的鍵在 Context 上下文按下時,如果鍵盤控制鍵 Modifiers 組合按下,那麼執行 Function.

鼠標鍵編號的方法是:1 左鍵,2 中鍵,3 右鍵。如果你的鼠標有輪子,那麼一般4表示往上滾動,5表示往下滾動。

Context是鼠標按下的位置,它可以是:

  • R(Root Window) 根窗口
  • n (n 是0...9 之間的一個數)。第 n 號窗口按鈕。按鈕是這樣編號的:
    1 3 5 7 9     0 8 6 4 2
    左邊是奇數右邊是偶數, 外面的大中間的小。
  • T(Title)標題欄
  • S(Sidebar)也就是邊框. 也可以用 '[', ']', '-' , '_' 分別表示左,右,上,下的邊框。
  • F(Frame)就是用來resize的那四個角落. 也可以用 '<', '^', '>' and 'v' 分別表示左上,右上,右下,左下的角落。
  • W(Working Area) 應用程序窗口工作區域
  • I(Icon window) 圖標化的窗口。

這些上下文可以組合。比如 "FST" 表示在frame, sidebar, 或者 title.

Modifiers 是鼠標操作時同時的鍵盤控制鍵。M 表示 "Meta",在PC上就是Alt,S: shift, C: ctrl. 還有 A: any, N: none. 也可以組合,比如"MS" 表示同時按下Alt-Shift.

Function 就是任意的FVWM操作了,可以是一個直接的命令,也可以是一個 FVWM 函數。

現在我們分析一下下面這個定義:

Mouse 3 W       SC      CloseOrNot
這個定義是說,在窗口上點擊鼠標右鍵,並且先按下 Shift-Ctrl,那麼調用 CloseOrNot 這個FVWM函數。這個函數會作用與當前鼠標所在的上下文,也就是一個窗口。函數是這樣定義的: 函數
DestroyFunc CloseOrNot
AddToFunc CloseOrNot
+ C Silent Close
+ M Nop

你可以把一系列的操作有條件的加入到一個叫做“函數”的結構裏,以後這個函數就可以像命令一樣被使用了。

AddToFunc 把動作附加到函數, 如果函數不存在就先創建這個函數。除了第一行,後面的行都以一個"+"號開頭,這說明以下是上一個命令(AddToFunc)的繼續。DestroyFunc 是爲了消除以前有可能定義過的函數體。這個函數 CloseOrNot 表示:

  • 如果是一個鼠標點擊(C), 那麼關閉這個窗口(Close), 但是如果現在不是在窗口上下文,也就是說,函數調用的時候沒有一個確定的目標,那麼不進行操作,而不是出現一個"+"字瞄準器讓用戶選擇窗口。 這就是 "Silent" 的含義。
  • 如果鼠標點下去之後移動了,也就是“拖動”(M),那麼不進行操作。
啓動函數和退出函數

在 FVWM 啓動和重新啓動時都會調用 StartFunction, 而且在首次啓動時會調用 InitFunction, 在重新啓動時會調用 RestartFunction, InitFunction 和 RestartFunction 都是在 StartFunction 之後調用。每次重起和完全退出時都要執行 ExitFunction.

如果你有什麼程序需要在FVWM啓動時啓動,那麼就把它加到合適的函數裏面去。比如,我的配置文件有這些內容:

DestroyFunc StartFunction
AddToFunc StartFunction         
+ I Module FvwmButtons MainPanel
+ I Module FvwmAuto 500 Raise Nop
+ I Module FvwmAnimate
+ I Module FvwmTaskBar
+ I Exec exec xdaliclock 
+ I Exec exec xloadimage -onroot -fullscreen ~/pic/cat_20.jpg
+ I Exec exec xsim

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

可見,我在第一次啓動時會啓動 xscreensaver 屏幕保護程序。-no-splash 是 xscreensaver 的參數。在每次重新啓動和第一次啓動時都要運行 FvwmButtons, FvwmAuto, FvwmAnimate, FvwmTaskBar 幾個模塊和 xdaliclock,一種 morph 數字的時鐘,然後用 xloadimage 放一張漂亮的圖片作爲桌面背景,最後啓動 xsim 中文輸入法。

退出和重起時,我特意關閉了那幾個啓動時打開的程序,因爲如果不關閉他們,像 xwin32, Exceed 這樣的 Windows X server 不會 Reset.

每個命令前的 "I" 表示 Imediately, 立即執行,聯想上面提到的 "C" 和 "M", 這個操作不等待任何鼠標動作。

窗口樣式

Style 語句用於設定窗口的樣式。你可以隨心所欲的讓不同的窗口有不同的樣式。語法爲:

Style stylename options

其中stylename是你的窗口的名字,窗口的class名字,或者窗口的resource名字。如果你不知道這些 X window 的術語,那現在就姑且當作窗口的名字好了,以後多看看 Xlib 的說明書你就會明白這些東西。窗口的名字有可能不同於程序的名字,你不知道它叫什麼名字可以用 xwininfo 程序或者 FvwmIdent 模塊來查詢。再次說明,FvwmIdent 是模塊,不能從 xterm 的命令行運行。

stylename 裏可以有 "*" 作爲通配符。比如你可以說

Style *term TitleAtLeft
讓所有以 "term" 結尾的那些窗口的標題攔都在左邊。比如 "xterm", "cxterm", "qterm", ... 都會採用這種樣式。

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)。

下面是說明所有名字以 "Fvwm" 開頭的窗口(在這裏一般都是 FVWM 內部的模塊),它們都沒有標題欄(NoTitle),而且是sticky,也就是說即使桌面切換,它們也一直顯示在屏幕上,邊框寬度爲 2, CirculateSkip 說明當FVWM要求輪詢窗口進行批量操作時,這些窗口不被計算在內。第3,4行說明 FvwmPager, FvwmBanner 這兩個模塊一直顯示在最上面。最後一行說明 FvwmButtons 模塊使用 toolbox.xpm 的圖標,需要鼠標點擊才能得到鍵盤聚焦(ClickToFocus)。

總的說來,options指出了控制窗口的基本樣式和政策,而不包括窗口各個部件具體的樣式,它包括以下幾個方面內容:

  • 窗口聚焦方式。是跟隨鼠標(FocusFollowsMouse),還是需要點擊才聚焦(ClickToFocus)...
  • 窗口標題欄。是否給窗口加上標題攔?如果加上,是放在左邊,上邊,還是下邊?注意這裏也不是設定具體標題樣式的地方,參看 TitleStyle.
  • 窗口應該顯示哪些按鈕。FVWM可以爲每個窗口設定最多10個按鈕,但是你通常用不到10個,這樣你可以設定對於某一個程序那些按鈕應該出現。注意這裏也不是設定按鈕樣式的地方,參看 ButtonStyle.
  • 窗口邊框樣式。邊框寬度,handle(就是邊框角上那個用來resize的東東)的寬度,邊框被鼠標按住的時候是否陷下去?...
  • 窗口圖標。用那個圖標作爲窗口iconify時候的圖標?
  • 窗口最大化,移動,改變大小操作時的樣式。是顯示窗口內容還是隻顯示一個“橡皮框”?還是讓尺寸小於某個值的窗口才在拖動時顯示內容?...
  • 窗口放置策略。窗口出現的時候,是層疊放置,最小遮擋放置,還是……?
  • 是否允許程序自己放置自己?這是一個政策問題,有些窗口程序啓動時會自己選擇一個位置出現,但是你可能會發現你不喜歡它那樣做,你可以設定NoPPosition, 不允許那個程序自作聰明。
  • 對瞬時窗口(transient window)的策略。transient window 是指類似彈出菜單,對話框之類的窗口。當它們出現的時候,你是否想給它們也加上標準的邊框?
  • 高級特性。還有很多很多選項比如是否允許窗口 backing store,這些如果你還不理解現在暫時不用管它。

以上每項都包含許許多多可以設定的東西。具體還是請參考 fvwm 的manpage。

菜單

一個窗口管理器怎麼能沒有菜單?FVWM的菜單是可以隨意自己定義的,它在任何時候出現在你想讓它出現的任何地方。一個菜單首先有一個定義,然後有一個激發這個菜單的條件,菜單的樣式也可以隨意定製。如果使用 PipeRead 命令和一些 shell 命令組合,你就可以用菜單的方式遍歷你的文件目錄樹,成爲一個“菜單式file manager”。

  • 菜單的定義

    菜單是由AddToMenu命令定義的,比如這樣一個菜單

    是這樣定義的

    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 指向圖標文件所在的目錄。你還可以在菜單里加入側面圖標,等等等等。

  • 菜單的消滅

    隨後的AddToMenu命令會把內容附加到菜單的末尾。所以如果你想重新定義一個菜單,就需要先把它銷燬掉。用

    DestroyMenu RootMenu
    
    就可以把剛纔那個 "RootMenu" 菜單消滅掉。
  • 菜單的激活

    光是定義了一個菜單你是不能馬上使用它的。這個菜單在什麼情況下出現?這個問題是需要你自己來決定,這也是顯示FVWM的完全可定製性的地方。比如,我們可以這樣定義一個激活菜單的方式:

    Mouse 1 R       A       Menu RootMenu Nop
    

    這句話的意思是:“當鼠標(Mouse)左鍵(1)在根窗口(R)上點擊,同時有任何控制鍵(A)按下,這個時候顯示叫做 RootMenu 的菜單。”

    但是有時候我們不容易在屏幕上找到一個可以看到根窗口的地方來點擊鼠標。我們可以再加一個定義:

    Mouse 3 A       MC      Menu RootMenu Nop
    

    這樣,當右鍵(3) 在任何地方(A)點擊, 同時有Alt(M)和Ctrl(C)按下,那麼彈出名叫 "RootMenu" 的菜單。

    上面的 "Nop" 表示的是鼠標在菜單上進行雙擊時的操作。我定義爲不操作。另外 Menu 還可以隨意定義菜單出現的位置,詳細請看 fvwm manpage。

  • 菜單的樣式

    菜單的樣式是由 MenuStyle 定義的:

    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
    

    這樣我規定:所有的菜單,他們使用 mwm 的行爲方式,彈出子菜單延時 160 ms,子菜單彈出時如果靠近屏幕邊沿放不下,那麼菜單整體移動使得子菜單剛好能彈出,前景色gold,背景色 gray40, 活動的項目(就是鼠標正在它上方的時候)前景色變爲白色,菜單使用字體 -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*, 背景是垂直的梯度顏色,一共64階,從 darkgray 變化到 MidnightBlue.

  • 動態菜單定義

    前面我們說過了,可以用 PipeRead 來構造一個動態菜單。現在舉一個簡單的例子:

    AddToMenu HomeDirMenu
    	PipeRead 'for i in $HOME/prog/*.c; /
    	do echo "+ $i Exec xterm -e vi $i"; done'
    

    當你激發這個菜單 HomeDirMenu, 就會出現你主目錄/prog下的所有C程序文件的列表,當你點擊其中一個就會啓動vi來編輯這個C程序。是不是很方便呢?你想一想,可以用怎樣無窮無盡的方式來構造一個菜單呢?

按鈕

窗口的標題欄上都有一些按鈕。那不是窗口程序自己的,而是WM給它們加上的。

FVWM 可以給窗口加上最多10個按鈕,它們不光可以實現基本的最大化,最小化,關閉,等功能。FVWM的靈活性允許你賦予按鈕幾乎任意的功能!

  • 按鈕編號

    按鈕是這樣編號的:

    左邊是奇數右邊是偶數, 外面的大中間的小。

  • 按鈕功能定義

    下面看看按鈕的功能是怎麼定義的,在鼠標和鍵盤一節我們已經知道怎麼定義鼠標了,按鈕的功能只不過是把鼠標與按鈕號碼組合在一起。

    比如我的窗口上一般有三個按鈕, 都在右上角,注意它們的編號:

         6 4 2

    他們的功能是這樣定義的:

    Mouse 1 4       A       Iconify
    Mouse 1 6       A       Close
    Mouse 3 2       A       Maximize-Func2
    
    其中 Maximize-Func2 是用了 system.fvwm2rc 裏一個函數:
    DestroyFunc Maximize-Func2	
    AddToFunc Maximize-Func2	"M" Maximize	 100 0
    +				"C" Maximize	 80 0
    +				"D" Maximize	 100 100
    

    如果鼠標右鍵在“最大化”按鈕上點擊(C)那麼高度增長爲屏幕的 80%, 寬度不變。如果按下鼠標右鍵後有拖動(M), 那麼高度增長爲屏幕高度(100%), 寬度不變。如果雙擊(D), 就是一般的最大化。

    爲什麼是右鍵?因爲我爲左鍵在這個按鈕上定義了更高級的 stroke 來改變窗口大小。我們稍後介紹。

  • 按鈕樣式

    按鈕的樣式是用ButtonStyle定義的。比如我的那三個按鈕實際上是如下幾句話定義的。

    ButtonStyle All -- UseTitleStyle
    ButtonStyle All ActiveDown VGradient 8 palevioletred black
    ButtonStyle 6 16 20x20@1 30x20@1 50x40@1 70x20@1 80x20@1 80x30@0 /
    	60x50@0 80x80@0 70x80@0 50x60@0 30x80@0 20x80@0 /
    	20x70@0 40x50@1 20x30@0 20x20@1
    

    右邊兩個按鈕的圖案是系統缺省的,那個"X"形按鈕是下面第三句話畫出來的。這種繪圖語句非常簡單。ButtonStyle 之後的數字是按鈕編號,後面一個數子表示一共有多少筆畫。後面的XxY@C都是筆畫的內容,XxY是座標, 座標都是用百分比表示的。@C 表示顏色, C是一個數字,0 表示陰影色,1 是高亮色,2 是背景色,3 是前景色,4 是移動光標而不畫線。

    你可以畫你自己的按鈕,也可以去拿別人設計好的來用。FVWM 的主頁上有很多人提供這種按鈕。

    第二個語句 "ActiveDown VGradient 8 palevioletred black" 設定了所有按鈕按下去還沒有鬆開鼠標時候的樣式,是一個顏色梯度。

其它樣式

我們已經知道 Style 可以決定窗口的樣式,MenuStyle 可以決定菜單的樣式,ButtonStyle 按鈕的樣式。其實還有 CursorStyle, TitleStyle, BorderStyle. 他們決定了光標,標題欄,邊框的樣式。他們都有多樣的語法,詳細的就看 magpage 吧。這裏就不照抄了。

條件命令

All, Any, Cond, Current, Direction, Next, None, Pick, WindowId, ... 這些命令是條件選擇窗口的辦法,它們讓你可以用非常多樣的方法,來確定你的操作需要對哪一個或者哪些窗口進行。比如:

All (Iconic) MoveToPage -1 -1
把所有圖標化的窗口都移動到桌面右下角的那一頁。
Key F5 A A Direction North Maximize True 0 growdown

以後按 F5 就可以讓當前聚焦窗口上面(North)那個窗口往下長大,直到被當前窗口擋住去路。你有時候想在VIM裏抄 Acrobat Reader 裏的內容,安排窗口大小的時候就可以用這招。

手寫操作 (Stroke)

你用過 EDA 軟件嗎?用過的話,你就可以知道鼠標動作(stroke)是多麼的方便!你是否想在你的窗口管理器裏也使用鼠標動作?

  • 讓 FVWM 支持 Stroke

    如果你的FVWM窗口管理器編譯進了 libstroke, 你就可以使用鼠標動作操縱程序。libstroke 是一個免費使用的 stroke 庫,你可以在 http://www.etla.net/libstroke/ 得到 libstroke. 下載那個爲 FVWM 準備的版本,編譯後安裝,然後再編譯 FVWM,它一般就會找到 libstoke,從而加入 stroke 的功能。

    比如我在屏幕上按住 ctrl, 用右鍵

    • 畫一個 "r" 字就可以啓動 rxvt
    • 畫一個 "V" 就可以啓動 vim
    • 畫出 "D" 右邊的弧線就可以啓動 IBM 智能辭典
    • 畫一個 "e" 啓動 emacs ...
    • 鼠標左右一晃,就可以啓動 xkill,再往某個窗口一點,就可以強制殺死不聽話的窗口
    • 在窗口裏右鍵往下一劃,就可以最小化窗口
    • 在窗口邊框上用右鍵……
    • 向上拖就可以使窗口往上一直長到被別的窗口擋住的地方
    • 向左拖就可以使窗口往左一直長到被別的窗口擋住的地方
    • 右……下……斜上…… 從邊框開始畫一個"L"形就可以回覆窗口原來大小

    當然這些控制方式都是你自己決定的, 這一切只需要在 .fvwm2rc 里加入一些Stroke語句. 因爲太多了,寫在主配置文件影響編輯, 這些語句被我寫到了另一個文件裏,然後在主文件用 Read 語句讀入。你可以在這裏下載我的fvwm.stroke文件作爲參考。

    你還可以定義非常高級的操作,你甚至可以這樣:按住 ctrl, 用鼠標中鍵畫出一條射線箭頭指向的那個窗口, 不論它在那個桌面,就會被吸過來,並且隨鼠標移動,你點擊左鍵就可以放置它。

  • 軌跡

    stroke 的原理很簡單,libstroke 可以識別出你在屏幕上畫出的軌跡,把它報告給FVWM,這樣FVWM根據軌跡的不同採取不同的操作。軌跡是由一個電話撥號盤的方式確定的。也就是說,把你畫出的東西分成9個區域,看你的鼠標依次經過那幾個區域。

                        1  2  3
    
                        4  5  6
    
                        7  8  9
    
    軌跡也可以用你的小鍵盤上的數字鍵來確認。看看你的小鍵盤:
                        7  8  9
    
                        4  5  6
    
                        1  2  3
    
  • Stroke 項目的定義

    在你的配置文件裏寫入一些 Stroke 語句:

    Stroke Sequence Button Context Modifiers Function
    
    比如:
    Stroke N7414789 0 A C Exec exec rxvt
    Stroke N7414759 0 A C Exec exec rxvt
    Stroke N74147589 0 A C Exec exec rxvt
    Stroke N7414756 0 A C Exec exec rxvt
    Stroke N74156 	0 A C Exec exec rxvt
    Stroke N74159 	0 A C Exec exec rxvt
    

    Stroke 關鍵字之後跟上軌跡說明。軌跡是一系列數字,如果數字前面有一個"N", 就表示我們採用小鍵盤的佈局,而不是電話撥號盤。你看我的那幾個軌跡,實際上是我們在寫 "r" 字母的時候有可能出現的幾種情況。

    比如,這個軌跡就是符合 "N7414589".

    軌跡之後是鼠標按鍵號碼。如果號碼不是0,那麼一旦識別到這個軌跡,就會馬上執行操作。但是如果號碼是0,那麼說明這個定義不是在任何時候識別到就馬上進行的。而是當 StrokeFunc 命令被調用的時候才進行。StrokeFunc 爲你提供了更多的靈活性。

    號碼之後是 Context Modifiers Function. 他們跟 Mouse, Key 的那兩個同名參數是一個意思,參看 鼠標和鍵盤.

  • StrokeFunc

    如果你的鼠標號碼是0. 那麼當 StrokeFunc 被調用的時候,這個軌跡如果被識別,就會執行相應的操作。比如:

    #Drag mouse 1 on the maxmize button
    Mouse 1 2 N StrokeFunc DrawMotion 
    
    現在看到了? 這就是我的最大化按鈕上對鼠標左鍵的綁定。DrawMotion 是 StrokeFunc 的一個可選參數,它可以讓軌跡在屏幕上被畫出來,這樣你可以清楚的看到你到底寫了什麼。

    我有如下的一系列 stroke 定義:

    #grow horizontal and vertically
    Stroke N258 0 TSF2 N Maximize True 0 growup
    Stroke N852 0 TSF2 N Maximize True 0 growdown
    Stroke N456 0 TSF2 N Maximize True growright 0
    Stroke N654 0 TSF2 N Maximize True growleft 0
    
    #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
    

    我的鼠標左鍵按下“最大化”按鈕之後可以進行繪畫,然後窗口會隨着軌跡的不同而採取各種各樣的改變大小的行動!

    我還有一個定義:

    Mouse 3 TSF N StrokeFunc DrawMotion
    
    這樣鼠標右鍵在窗口標題欄,邊框,frame 上繪畫時也會觸發 StrokeFunc 函數,達到跟左鍵在“最大化”按鈕上繪畫同樣的效果。發現了吧?StrokeFunc 爲我省去了重複的軌跡定義,否則我需要爲“左鍵+最大化按鈕”和“右鍵在邊框”定義兩套 stroke.
  • 實例分析

    我們來分析一種可能的執行情況:用鼠標左鍵按下“最大化”按鈕(2),然後向右畫。就像這個樣子:

    當鼠標左鍵在“最大化”按鈕(2)上按下之後,如果沒有鍵盤控制鍵按下(N),而那麼根據"Mouse 1 2 N StrokeFunc DrawMotion", FVWM就會發現應該調用 StrokeFunc.

    StrokeFunc 會馬上記錄鼠標按下的時候有哪些控制鍵按下了,現在是沒有控制鍵(N).

    然後它發現鼠標隨即向右畫出了一條線,看看你的小鍵盤,這是N456。StrokeFunc 就會在已經定義的 Stroke 裏去找,是否存在這樣的一個定義,它的前面部分是

    Stroke N456 0 2 N ...
    
    它發現有一個
    Stroke N456 0 TSF2 N Maximize True growright 0
    

    它的 Context: TSF2 包含了標題欄按鈕2。鼠標動作開始時沒有控制鍵按下,而這個項目的Modifiers裏也是N. 那麼這是一個符合的項目。所以進行操作 "Maximize True growright 0":把窗口向右擴大,直到被另一個窗口或者屏幕邊沿擋住。

    注意控制鍵都是在動作開始時就已經記錄下來了。如果你在繪畫的途中放開了或者按下了控制鍵是不會改變識別的效果的。

  • 怎樣提高識別率

    通常不要定義太複雜的軌跡,因爲變化太多了就不容易識別。左右晃一晃,上下搖一搖,轉個圈兒,……已經可以完成你很多任務了。

    如果是複雜的 stroke, 比如寫一個字母,你需要定義很多相似的 stroke,否則有時不能匹配。如果你不能確定會出現那些軌跡,你可以給 StrokeFunc 一個參數,比如:

    Mouse 1 2 N StrokeFunc EchoSequence
    

    然後你在屏幕上多畫幾次你的那個字母,無論它是否匹配一個定義,FVWM 會在啓動它的那個終端輸出你畫出的軌跡號碼。那些就是你寫這個字母時有可能出現的軌跡,你把這些序列都加到你的配置文件,這樣就提高了識別率。

    注意這個輸出號碼的終端很有可能是 tty1,在Linux下你需要Ctrl-Alt-F1切換到tty1才能看到輸出。如果你不喜歡這麼麻煩,你可以在啓動X的時候只啓動一個 xterm, 然後在這個 xterm 裏面啓動 fvwm.

  • 鍵盤觸發 Stroke

    stroke 也可以由鍵盤來觸發。比如:

    Key F6 A C StrokeFunc DrawMotion NotStayPressed
    

    按下 Ctrl-F6 之後,FVWM就會調用 StrokeFunc, 由於我們設定了 NotStayPressed 參數,繪畫一直會延續到一個鼠標鍵按下的時候才結束。這時你就可以用鼠標移動畫出一個軌跡,然後按一下鼠標。

模塊

模塊是FVWM可以擴展的奧祕。模塊是通過管道跟FVWM通信的程序,它們必須由FVWM啓動(fork). 也就是說,你可以從 FvwmConsole 來啓動這些模塊,也可以用菜單,鼠標,熱鍵……來啓動。但是就是不能從 xterm 或者 rxvt 敲入命令來啓動它們。

  • 你有沒有發現。當你的鼠標移動到窗口後,如果它被別的窗口擋住了,它並不會跑到上面來。如果你想讓它自動上來,你可以使用 FvwmAuto 模塊來實現一個簡單的“自動提升”功能。我的 StartFunction 裏有如下內容:
    AddToFunc StartFunction   	
    + I Module FvwmAuto 500 Raise Nop
    
    其實你還可以用 FvwmAuto 實現非常複雜的自動提升功能。
  • 你想讓你的窗口圖標化(Iconify) 和取消圖標化(Deinconify) 的時候都有漂亮的動畫嗎?用以下設定來配置你的 FvwmAnimate 模塊,然後啓動它,就可以有眼花繚亂的效果了 :)
    *FvwmAnimate: Delay 25
    *FvwmAnimate: Effect Random
    *FvwmAnimate: Width 3
    
    這些行是對 FvwmAnimate 的配置,模塊的配置命令都是 "*" 號開始的。
  • 你想要一個 Windows 那樣的任務欄嗎?啓動 FvwmTaskBar 模塊就行了。
  • 想要一個 Pager? FvwmPager 可以提供你用不完的功能。參看FvwmPager.
  • Drag & Drop? 啓動 FvwmDragWell, 就可以讓支持 XDND 的程序工作。
  • 你想這樣一種功能:每次當名叫 XXX 的程序出現時,就把它大小變爲 400x300, 移動到屏幕右邊,然後啓動一個 rxvt 跟它作伴?用 FvwmEvent 可以輕鬆達到你的目的。
  • 你想做一個簡單的圖形界面程序?用 FvwmScript 可以快速的達到你的目的。
  • 寫配置文件太冗長了?用 FvwmM4 可以讓你用 M4 宏處理語言來預處理配置文件。
  • 你想有更加超級的操縱方式?FvwmPerl 可以讓你使用 Perl 腳本的方式來操縱 FVWM.
模塊的功能可能很複雜,它們都有自己分別的 manpage. 下面幾節我們介紹一些常用的模塊。 FvwmPager

既然 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
這些行是對 FvwmPager 的配置,模塊的配置命令都是 "*" 號開始的。 在 FVWM 裏啓動它:
Module FvwmPager 0 3
FvwmButtons

上面的Pager不錯吧?不過它總是在屏幕上佔那麼一塊位置,有沒有辦法讓它可以在需要的時候才伸出來呢?你可以用 FvwmButtons 把FvwmPager包裝起來實現這個功能。

這裏是我的一個簡單的配置:

*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設置了一個 button 叫做 "MainPanel". 你可以用:
Module FvwmButtons MainPanel
來啓動它. 它啓動時是這個樣子:

掛在屏幕左上偏右一點的地方,既沒有擋住左邊的按鈕,又不會擋住窗口的下拉菜單。點一下就會展開,展開以後就是這個樣子:

再點就會縮回去。

FvwmButtons 可以提供的功能遠遠不止這些。FvwmButtons 是一個非常強大的模塊。你有興趣可以看看它的 manpage.

FAQ

這一節來看看我遇到過的一些問題。

  1. 爲什麼 FVWM 不能用圖片作爲背景?

    不熟悉Xwindow的人經常問這種問題。答案是FVWM確實不能設置複雜的高清晰圖片作爲背景,但是你卻可以用圖片作爲背景。原因是:設置背景根本不是WM的職責,你需要用其它程序,比如 xloadimage, xv, ... 在根窗口上放置一幅圖片,那就是所謂的“桌面背景”。你可以把它加入你的啓動函數,一個 xloadimage 的例子可以在上面看到

  2. FVWM怎麼鎖定屏幕呢?

    你又問到一個容易混淆的問題。鎖定屏幕也不是WM必須有的功能。幾乎所有WM都是調用另外一個程序,比如 xscreensaver 來鎖定屏幕和提供屏幕保護,然後在它們的菜單里加入對 xscreensaver 配置程序 xscreensaver-demo 的調用。看起來好像是WM提供了屏幕保護功能,讓很多用戶模糊了WM的職責。

    你可以把 xsreensaver 加入到FVWM的啓動函數裏。參看啓動函數和退出函數.

  3. 爲什麼 FVWM 的窗口標題不能顯示漢字?

    FVWM當然能顯示漢字了,它是一個國際化的程序。原因在於你沒有設置好漢字字體。你可以在配置文件里加入漢字字體的設定:

    Style * Font  -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*
    
    simsun 是我機器上一種同時可以支持漢字和英語編碼的字體,如果你的字體只有漢字編碼,那麼你的英文全部都會“亂碼”,這時你需要在後面再加一個英文字體。比如:
    Style * Font  "-cjacker-magicsong-medium-r-*-*-14-*-*-*-*-*-gb2312.1980-0,*-r-*"
    

    類似的,pager,windowlist 都有自己的字體設定,你需要把它們都設置爲你喜歡的中文字體。

    另外,據說 FVWM 2.5 以前的版本對漢字支持不好。我沒有用過 2.4.x,不知道怎麼解決。如果你遇到這個問題就升級到 2.5.x 吧。

  4. FVWM 有工具條嗎?

    有。啓動 FvwmTaskBar 模塊就行了。你還可以把它配置的非常漂亮。這裏給出一個我的簡陋的配置方案。

    Style FvwmTaskBar HandleWidth 0, BorderWidth 0
    *FvwmTaskBar: UseSkipList
    *FvwmTaskBar: AutoStick
    *FvwmTaskBar: DeskOnly
    *FvwmTaskBar: Action Click1 DeiconifyRaiseAndFocus
    *FvwmTaskBar: Action Click2 Iconify On
    *FvwmTaskBar: Action Click3 Lower
    *FvwmTaskBar: MailCommand Exec exec rxvt -e mutt
    *FvwmTaskBar: 3DFvwm
    *FvwmTaskBar: StartName FVWM
    *FvwmTaskBar: StartMenu RootMenu
    *FvwmTaskBar: Font  -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*
    *FvwmTaskBar: SelFont  -*-simsun-medium-r-*-*-14-*-*-*-*-*-*-*
    *FvwmTaskBar: ShowTips
    *FvwmTaskBar: ClockFormat 
    *FvwmTaskBar: WindowButtonsRightMargin 20 
    
    *FvwmTaskBar: Back seagreen
    *FvwmTaskBar: Fore gold2
    *FvwmTaskBar: FocusFore cornsilk
    *FvwmTaskBar: IconBack darkgreen
    *FvwmTaskBar: IconFore white
    

    另外,FvwmButtons 模塊提供了更加複雜的功能。你可以把很多小程序(xclock,biff...)和模塊(FvwmIconMan)嵌入到它裏面。形成一個複雜的工具條。詳情請 man FvwmButtons。你也可以使用 KDE 的 kicker 工具條和 Gnome 的 gnome-panel. 請看後面

  5. FVWM 能不能像 Windows 那樣用 Alt-Tab 切換窗口?

    能。把這行加入 .fvwm2rc:

    Key Tab A M WindowList Root c c NoDeskSort
    
    這個綁定不知道什麼時候好像成了 FVWM 缺省的。如果你不喜歡,那麼加入:
    Key Tab A M -
    
    取消這個定義。
  6. 我不想要鼠標移動到窗口上就自動聚焦的方式怎麼辦?

    FVWM 缺省的聚焦方式是 MouseFocus,也就是說,鼠標如果移動到哪個窗口,那個窗口就得到鍵盤聚焦。如果你想用 Windows 那樣的需要點擊鼠標才聚焦,那麼你可以用 ClickToFocus 方式:

    Style * ClickToFocus, ClickToFocusPassesClick
    
  7. 我用 MouseFocus 方式,可是當我的一個窗口被 Lower 後,我只能把鼠標移到其它窗口再移回來才能重新提升它。

    缺省的 MouseFocus 方式不會在點擊時提升窗口。如果你想點擊窗口時提升它,那麼加入配置:

    Style * MouseFocusClickRaises
    
  8. 怎樣才能使窗口獲得焦點後自動提升?

    你需要使用 FvwmAuto 模塊。把 FvwmAuto 加入你的起動函數:

    AddToFunc StartFunction   	
    + I Module FvwmAuto 500 Raise Nop
    
  9. 爲什麼 Acrobat Reader 打開一個全屏 PDF 文件後,還原爲窗口還是不能移動?

    把這行加到你的配置文件就行了:

    Style "AcroRead"	VariablePosition, VariableUSPosition
    
  10. 怎樣才能讓 ImageMagick 或者 Gimp 的幾個小窗口同時提升或者下降呢?

    把這行加到你的配置文件就行了:

    Style "Display"	RaiseTransient LowerTransient StackTransientParent
    Style "Gimp"	RaiseTransient LowerTransient StackTransientParent
    
  11. 屏幕保護出現時,XSIM 輸入法的狀態窗口爲什麼不消失呢?

    這是 XSIM 的一個 bug, 它設置了狀態窗口的 OverrideRedirect 屬性以至於沒有窗口管理器能夠管理它。我已經幫助修正了這個 bug。你只需要在 plugins/StatusPanels/std/statuspanel_std.cpp 的

    TWstring * TStatusPanel_STD::create(Obj_Config * conf, Status_Pack * sp)
    

    函數末尾 return NULL; 之前加入以下兩行:

    wa.override_redirect = False;
    set_winattr(CWOverrideRedirect, &wa);
    

    問題就已經解決了。

    如果你還不滿意,你想讓 FVWM 可以設定 xsim 的樣式,那麼你可以把這個函數中設置 OverrideRedirect 的那幾行代碼去掉。

    /*
    XSetWindowAttributes wa;
    wa.override_redirect = True;
    set_winattr(CWOverrideRedirect, &wa);
    */
    
    自己設置它的屬性。我們可以給它邊框,也可以不給它邊框。你可以把這些配置寫到你的 .fvwm2rc 得到一個比較好的效果。
    Style "XSIM"    Layer 7, NoTitle, HandleWidth 1, Sticky, WindowListSkip
    

    注意如果去掉了 OverrideRedirect 屬性,在某些不能隨意定製窗口樣式的窗口管理器裏,狀態窗口會被包上厚重的標題欄和邊框!

    你可以試試 fcitx 輸入法服務器。我現在換用這個了。我覺得比 XSIM 好用。直接安好就可以了,沒有以上問題 :)

  12. FVWM 能和KDE, Gnome 一起工作嗎?

    KDE 和 Gnome 都是完整的桌面系統,包括了WM和其它很多東西。FVWM 只是一個WM。FVWM可以替代 KDE 缺省的 kwin,或者 Gnome 缺省的 sawfish 成爲它們的WM。

    • 只用KDE和Gnome的工具條

      很多時候 Gnome 和 KDE 的程序是跟他們的桌面系統可以分開使用的。其實你有可能只需要它們漂亮的panel。

      Gnome 的工具條叫做 gnome-panel, 在 xterm 啓動一個就行了。

      KDE 的工具條叫做 kicker. 注意 KDE 有些程序需要 dcopserver, 你可以先啓動 dcopserver。

      KDE 和 gnome 的panel上的pager和fvwm的FvwmPager都是相通的,所以你可以用它們任何一個來切換桌面 :)

      如果你在kde的任務條用右鍵選擇“總在最前”可能不起作用,因爲現在它們得完全聽fvwm的話不過你可以給它們額外的權力,請參考fvwm manpage 的有關EWMH 的部分

    • 完全啓動Gnome和KDE與FVWM一起工作

      還有些kde程序不知道用了什麼通信方式,啓動後就dump了。你可以用 startkde 來啓動整個 KDE 系統。一般來說它們都可以與fvwm一起很好的工作。

      Gnome 的啓動命令叫做 gnome-session. 它也可以完全與 fvwm 一起工作。

      這樣你就可以用 fvwm 的方式來控制所有桌面系統的窗口了。嘿嘿

    看看下面這幅圖,KDE 正和 fvwm 在一起。嘿嘿。點擊可以放大。

    你甚至可以讓 Gnome 和 KDE 同時出現。不過估計除了耍酷,沒人會像這樣做:

特種技巧
  1. 即時戰略遊戲式的控制窗口

    很多即時戰略遊戲都可以對士兵等進行分組比如選定一組士兵後按 Ctrl-Alt-1,可以把一組士兵標記爲第1小分隊以後按 Ctrl-1 就可以讓這些士兵待命。

    其實FVWM可以很容易把一些窗口當成士兵。只要把這些行加入 .fvwm2rc

    Key 0 WI MC Key 0 A C WindowId $[w.id] WarpToWindow 50 50
    Key 1 WI MC Key 1 A C WindowId $[w.id] WarpToWindow 50 50
    Key 2 WI MC Key 2 A C WindowId $[w.id] WarpToWindow 50 50
    ....
    Key 9 WI MC Key 9 A C WindowId $[w.id] WarpToWindow 50 50
    

    聚焦一個窗口後按 Ctrl-Alt-n, 就把它標記爲n號。以後不論什麼時候按 Ctrl-n,就會回到這個窗口。

    $[w.id] 是 FVWM 2.5.6 以後使用的表示窗口id的變量。較老版本的FVWM使用 $w 來表示窗口id。 2.4.x 的用戶試試:

    Key 0 WI MC Key 0 A C WindowId $w WarpToWindow 50 50
    Key 1 WI MC Key 1 A C WindowId $w WarpToWindow 50 50
    Key 2 WI MC Key 2 A C WindowId $w WarpToWindow 50 50
    ....
    Key 9 WI MC Key 9 A C WindowId $w WarpToWindow 50 50
    

    這顯示 Key 等命令全都可以嵌套使用!當然你可以用類似的辦法得到更令人驚訝的效果!just imagine!

    ................

    ................

    想到了嗎?好了,來看看一個更超級的用法。在你的 .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
    
    Key 0 A M All (State 0) GroupFunc
    Key 1 A M All (State 1) GroupFunc
    Key 2 A M All (State 2) GroupFunc
    Key 3 A M All (State 3) GroupFunc
    Key 4 A M All (State 4) GroupFunc
    Key 5 A M All (State 5) GroupFunc
    Key 6 A M All (State 6) GroupFunc
    Key 7 A M All (State 7) GroupFunc
    Key 8 A M All (State 8) GroupFunc
    Key 9 A M All (State 9) GroupFunc
    Key a A M All (State 10) GroupFunc
    ....
    

    以後按 Ctrl-Shift-n,就可以把當前聚焦窗口設置爲“第n組”(State n)。n 可以從 0 到 31。以後我們可以按 Alt-n 來把第n組的窗口都移動到當前 page,全部 deiconify 並且提升--待命!

    你是否聽到那些窗口在說:“Yes, Sir?” 你能想出更好玩的用法嗎?發揮你的想象力吧!

我的 .fvwm2rc 和 fvwm.stroke

這裏給出我自己的 .fvwm2rc 和 fvwm.strokes 文件作爲參考。我自認爲不是很漂亮,但是卻很方便。fvwm.strokes 是被 Read 命令讀入 .fvwm2rc 的。

我的配置文件定義了很多奇怪的熱鍵加鼠標的用法,還有 stroke。你肯定不希望馬上拷貝到你的目錄裏使用,因爲你會不知道怎麼用了 :)

[.fvwm2rc] [fvwm.strokes]


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章