X11/窗口管理器/ctwm 指南
CTWM 是 TWM 的一个分支,允许使用 多个桌面,它是一个可定制的、轻量级且最小的 重新父级化窗口管理器,在各种较旧和较新的 UNIX(及其衍生系统)操作系统上使用。目前它不符合 ICCCM 或 EWMH 标准,但具有一些 GNOME 支持(有一个名为 ETWM 的分支,声称正在开发中,符合 ICCCM 2.0 和 NetWM/EWMH 标准)。
CTWM 的起源可以追溯到 1987 年,当时 Tom LeStrange 编写了 Tom 的窗口管理器。1989 年,TWM 被 X Consortium 采用,成为 X11 的标准窗口管理器,并更名为 Tab Window Manager。克劳德·勒科曼德尔 <[email protected]> 受 HP 的 MWM 基窗口管理器(提供可配置的工作区)的启发,将 多个工作区 添加到 TWM 中,并在 1992 年将其发布为 CTWM。2003 年,当克劳德停止开发时,该项目由理查德·莱维特 <[email protected]> 继续。2014 年之后,马修·富勒 <[email protected]> 接管了该项目。截至本文撰写之时(2017 年年中),他是当前维护者。
CTWM 窗口管理器的特点包括
- 堆叠窗口
- 支持 多个桌面
- 用 C 编写
- 自动升起或点击获取焦点模式
- 支持 M4 用于用户定义的宏
- 支持 XToolkit 客户端(使用 XLib 和 XResources)
- 窗口装饰(包括 边框 和带有可配置 标题按钮 的 标题栏)
- "形状" 窗口
- 通过 标题按钮、指针(鼠标)按钮或键盘支持弹出菜单
- 支持图标管理
- 支持主题和自定义颜色
- 支持桌面壁纸
- 支持 XPM、JPEG 和 IMCONV'd 图像
- 支持 GNOME
- 支持声音
- 开源 并在许多平台上免费提供
CTWM 是一个传统的 X 窗口管理器,与现代 X "桌面"、Microsoft Windows 或 Mac OS/X 不同。没有图形化的 "设置" 管理器。启动 CTWM 和自定义您的环境是通过用户会话管理器或通过编辑您的 X 配置文件来完成的,例如 ~/.xinitrc、~/.xprofile 等,使用普通的文本编辑器。以下操作是正常编译的默认值,您的系统管理员可能已将默认值配置得不同,或者编译了没有某些功能的 CTWM,YMMV。
您的 ~/.xinitrc 文件是一个由 xinit 及其前端 startx 读取的 shell 脚本。xinit 程序启动 X Window System 服务器,并在未使用显示管理器的系统上作为第一个客户端程序运行。它用于在启动 X 时启动守护程序(后台运行的应用程序)、设置环境以及执行窗口管理器和其他程序。您的系统管理员可能已在您的主目录中放置了一个 .xinitrc 文件,其中包含一些默认的启动应用程序和默认的窗口管理器或桌面环境。在文本编辑器中打开它(尝试 nano .xinitrc
)并向下滚动到文件末尾。您应该将默认窗口管理器(通常是 twm)更改为 ctwm,并在保存文件之前进行任何其他更改。
在 CTWM 的默认配置中(可能位于 /usr/lib/X11/[c]twm/system.ctwmrc 中),标题栏 有两个按钮
- 右侧 "调整大小" 按钮(嵌套的正方形):用户将鼠标指针拖动到要移动的边缘,然后在窗口达到所需大小后释放。
- 左侧 "最小化" 按钮(点):将窗口最小化。单击图标以恢复它。
左键单击 标题栏 或突出显示的区域,会将窗口提升到窗口堆栈的顶部;按住按钮并将轮廓拖动到屏幕上的新位置,然后释放按钮,会将窗口移动到那里。
左键单击桌面会弹出一个默认操作菜单(XToolkit 应用程序)。
- "Xterm" 一个 "终端",您可以使用它来启动程序或访问远程计算机。
- "Calculator" 一个计算器
- "Xman" 一个用于浏览可用的程序文档的手册浏览器。
- "Xmag" 一个屏幕放大镜。
- "Restart" 重新启动 CTWM,重新加载 .ctwmrc 文件。(在编辑您的 ~/.ctwmrc 文件后使用)
- "Exit" 退出 CTWM(并关闭 X 窗口)。
在桌面上右键单击会弹出一个窗口操作菜单。选择操作,然后左键单击要操作的窗口。
- "Occupy" 允许您选择窗口占据哪些工作区。
- "Occupy All" 将窗口复制到所有 "WorkSpaces"。
- "Iconify" 将窗口图标化/取消图标化。
- "Refresh" 如果屏幕上有 "artifacts" 则刷新屏幕。
- "Vanish" 如果窗口占据了其他工作区,则将其从当前工作区中删除。
- "Info" 获取窗口的 X-Windows 信息。
- "Resize" 点击并拖动鼠标指针到要移动的窗口边缘,然后在窗口达到所需大小后释放鼠标。
- "Move" 勾勒并移动屏幕上的窗口。
- "Adopt Window" (请参阅 "man" 页面)
- "Animate" 重新开始动画(如果有)。
- "Don't animate" 停止动画(如果有)。
- "Send Delete" 关闭窗口。
- "Kill Window" 关闭窗口的最后手段(用于行为异常的程序)。
- "Pin menu" 使菜单停留在屏幕上。
没有停靠栏、托盘或菜单栏,但如果您启动一个独立的合成管理器(例如 Compton),则可以添加这些。
CTWM 的配置是通过使用普通的文本编辑器编辑 ~/.ctwmrc 文件来完成的。如果您有一个 /twmrc 文件,它会使用该文件。查看 Dan Lilliehorn 的广为人知的 "Complete & Commented .ctwmrc" 在 ctwm.org 上(注意:自大约 3.6 版之后就没有更新)。窗口管理器的 "Feel" (来自 "Look-and-Feel") 主要有两种类型:"Focus-follows-mouse" (有时称为 "Auto-Raise");或者 "Click-to-focus"。CTWM 可以同时实现两种方式。配置文件主要包含三个部分:变量;绑定;和菜单。在讨论窗口装饰之后,我们最后会看看菜单部分。
这是一个典型的自动提升变量部分,您的情况可能有所不同。
### GENERAL CTWM CONFIG ## Don't grab server when popupping up menus and moving opaque windows NoGrabServer ## Respect program-requested positions: "on", "off" or "non-zero" UsePPosition "non-zero" ## Don't use the default titlebuttons and bindings #NoDefaults ## Place windows in a pseudo-random location: "on", "off", "all", "unmapped" RandomPlacement "on" ## Remember if window was iconified when restarting window manager RestartPreviousState ## Raise window when one click on it #RaiseOnClick ## Use Button 1 to raise a window #RaiseOnClickButton 1 ## Automticcally raise window when cursor enters the window AutoRaise ## if Autoraise, wait N ms before raising it RaiseDelay 250 ## Transient windows get focus automatically when created AutoFocusToTransients ## Transient window on top if n% smaller than parent window TransientOnTop 50 ## Don't send key events from the titlebar ## and icon managers to the application #NoTitleFocus # Use sloppy Focus #SloppyFocus # Don't use pointer-driven keyboard focus, but click to focus #ClickToFocus # Don't wait for the cursor to cross an edge to resize the window AutoRelativeResize # Don't move windows Off the screen #DontMoveOff # Moving the small window in the WorkspaceManager will move the actual window ReallyMoveInWorkspaceManager # Keep menus up if the cursor has not yet been entered by the pointer StayUpMenus ### WINDOWS RING WindowRing { ## "AppsClassName" } ## f.wrapring warps only to windows visible in the current space WarpRingOnScreen ## Don't raise windows when pointer is wraped to them NoRaiseOnWarp ## Deiconify any iconified windows it encounters. WarpUnmapped
这是一个典型的自动提升绑定部分,您的情况可能有所不同。
## Key bindings # Ignore caps lock (lock) and num lock (m2) modifiers IgnoreModifier { lock m2 } # Raise/lower windows with C-S-Up/Down "Up" = c s : window : f.raise "Down" = c s : window : f.lower # You can use your favorite keys to go directly # the preferred apps #"F5" = : all : f.warpto "emacs" #"F6" = : all : f.warpto "Mozilla-bin" #"F7" = : all : f.warpto "bitchx" # Use the windowring using M-Tab/C-Tab # (you must define apps that go in the windowring, see WindowRing above) "Tab" = m : window : f.warpring "next" "Tab" = c : window : f.warpring "prev" ## Workspaces and screens # Win+Up : change workspace "Up" = m4 : all : f.prevworkspace # Win+Down : change workspace "Down" = m4 : all : f.nextworkspace # Win+Right/Left: change screen "Left" = m4 : all : f.warptoscreen "back" "Right" = m4 : all : f.warptoscreen "next" ## Windows placement # Iconify window with Ctrl+Esc, Deiconify with Win+Esc "Escape" = c : window : f.iconify "Escape" = m4 : iconmgr : f.deiconify "Return" = : iconmgr : f.deiconify # Ctl+Win+Right/Left: push window "Left" = c m4 : window : f.pack "left" "Right" = c m4 : window : f.pack "right" "Up" = c m4 : window : f.pack "top" "Down" = c m4 : window : f.pack "bottom" # Win+Tab: forward in iconmgr "Tab" = m4 : all : f.forwiconmgr # Win+a: backward in inconmgr "a" = m4 : all : f.backiconmgr # Pointer bindings ## In Windows, icons and iconmanager ## Raise/lower window with Button1 and Button3, iconify with Button2 Button1 = m : window|icon : f.lower Button2 = m : window|icon : f.iconify Button3 = m : window|icon : f.raise ## Move window with Button1 in title, Raise/lower it with Button 2 Button1 = : title : f.move Button2 = : title|frame : f.raiselower ## Move window with C-Button2 Button2 = c : window : f.move ## Resise window with C-Button3 and with Button1 on frame Button3 = c : window : f.resize Button1 = : frame : f.resize ## Move or de-iconify icons with button 1 Button1 = : icon : f.function "move-or-iconify" # Squeeze window with mouse wheel Button4 = : title : f.squeeze Button5 = : title : f.squeeze # raise window with a click on the icon manager Button1 = : iconmgr : f.iconify ## Bind menus to pointer # Mouse Buttons on the root window open main menus Button1 = : root : f.menu "defops" Button2 = : root : f.menu "TwmWindows" Button3 = : root : f.menu "TwmIcons" # Cltr+Mouse Buttons on the root window open secondary menus Button1 = c : root : f.menu "TwmWorkspaces" Button2 = c : root : f.menu "TwmAllWindows" Button3 = c : root : f.menu "windowops" # Open windowops menu also on windows titlebars and iconmanager Button3 = : title|iconmgr : f.menu "windowops"
这是一个典型的点击聚焦变量部分,您的情况可能有所不同。
### GENERAL CTWM CONFIG ## Don't grab server when popupping up menus and moving opaque windows NoGrabServer ## Respect program-requested positions: "on", "off" or "non-zero" UsePPosition "non-zero" ## Number of outline to be displayed when (de-)iconnifying a window Zoom 0 ## Don't use the default titlebuttons and bindings #NoDefaults ## Place windows in a pseudo-random location: "on", "off", "all", "unmapped" RandomPlacement "on" ## Remember if window was iconified when restarting window manager RestartPreviousState ## Raise window when one click on it RaiseOnClick ## Use Button 1 to raise a window RaiseOnClickButton 1 ## Automticcally raise window when cursor enters the window #AutoRaise ## if Autoraise, wait N ms before raising it #RaiseDelay 250 ## Transient windows get focus automatically when created AutoFocusToTransients ## Don't send key events from the titlebar ## and icon managers to the application #NoTitleFocus # Use sloppy Focus #SloppyFocus # Don't use pointer-driven keyboard focus, but click to focus ClickToFocus ### WINDOWS RING WindowRing { ## "AppsClassName" } ## f.wrapring warps only to windows visible in the current space WarpRingOnScreen ## Don't raise windows when pointer is wraped to them NoRaiseOnWarp ## Deiconify any iconified windows it encounters. WarpUnmapped
这是一个典型的点击聚焦绑定部分,您的情况可能有所不同。
## Key bindings # Ignore caps lock (lock) and num lock (m2) modifiers IgnoreModifier { lock m2 } # Change workspace with C-Up/Down "Up" = c : all : f.prevworkspace "Down" = c : all : f.nextworkspace # Raise/lower windows with C-S-Up/Down "Up" = c s : window : f.raise "Down" = c s : window : f.lower # You can use your favorite keys to go directly # the preferred apps #"F5" = : all : f.warpto "emacs" #"F6" = : all : f.warpto "Mozilla-bin" #"F7" = : all : f.warpto "bitchx" # Walk the windowring using M-Tab/C-Tab # (you must define apps that go in the windowring, see WindowRing above) "Tab" = m : window : f.warpring "next" "Tab" = c : window : f.warpring "prev" ## Workspaces and screens # Win+Up : change workspace "Up" = m4 : all : f.prevworkspace # Win+Down : change workspace "Down" = m4 : all : f.nextworkspace # Win+Right/Left: change screen "Left" = m4 : all : f.warptoscreen "back" "Right" = m4 : all : f.warptoscreen "next" ## Windows placement # Iconify window with Ctrl+Esc, Deiconify with Win+Esc "Escape" = c : window : f.iconify "Escape" = m4 : iconmgr : f.deiconify # Ctl+Win+Right/Left: push window "Left" = c m4 : window : f.pack "left" "Right" = c m4 : window : f.pack "right" "Up" = c m4 : window : f.pack "top" "Down" = c m4 : window : f.pack "bottom" # Win+Tab: forward in iconmgr "Tab" = m4 : all : f.forwiconmgr # Ctrl+a: backward in inconmgr "a" = m4 : all : f.backiconmgr # Pointer bindings ## In Windows, icons and iconmanager ## Raise/lower window with Button1 and Button3, iconify with Button2 Button1 = m : window|icon : f.lower Button2 = m : window|icon : f.iconify Button3 = m : window|icon : f.raise ## Move window with Button1 in title, Raise/lower it with Button 2 Button1 = : title|frame : f.move Button2 = : title|frame : f.raiselower ## Move window with C-Button2 Button2 = c : window : f.move ## Resise window with C-Button3 Button3 = c : window : f.resize ## Move or de-iconify icons with button 1 Button1 = : icon : f.function "move-or-iconify" ## Activate window from the incon manager with button1 Button1 = : iconmgr : f.function "activate-me" # Squeeze window with mouse wheel Button4 = : title : f.squeeze Button5 = : title : f.squeeze ## Bind menus to keys # Mouse Buttons on the root window open main menus Button1 = : root : f.menu "defops" Button2 = : root : f.menu "TwmWindows" Button3 = : root : f.menu "TwmIcons" # Cltr+Mouse Buttons on the root window open secondary menus Button1 = c : root : f.menu "TwmWindows" Button2 = c : root : f.menu "TwmWorkspaces" Button3 = c : root : f.menu "windowops" # Open Window menu also on windows titlebars and iconmanager Button3 = : title|iconmgr : f.menu "windowops"
用户界面样式有很多选择:OPEN LOOK,使用标题栏上的一个按钮,就像早期 SUNview 所使用的那样;ICE,这是一种传统的 UNIX 外观,使用两个按钮,就像 TWM 所使用的那样;Motif 三按钮样式,就像 MWM 所使用的那样,并在 *Motif Style Guide* 中进行了描述;以及现代 X 窗口管理器和 X 桌面环境(如 Gnome 和 KDE)的所谓 "Clean" 四按钮样式。
Open Look 在左侧使用一个标题按钮,用于将窗口图标化。在标题栏上点击按钮 1(通常是鼠标左键)会将窗口提升到窗口堆栈的顶部;按钮 2(中间按钮)会移动窗口;按钮 3(通常是右键)会弹出一个菜单(通常是针对窗口执行的操作)。
在默认的 ICE 配置中,标题栏上有两个按钮
- 右侧 "Resize" 按钮 (f.resize):用户将鼠标指针拖动到要移动的边缘,然后在窗口达到所需大小后释放鼠标。
- 左侧 "Iconify" 按钮 (f.iconify):将窗口图标化。
在 标题栏 上的 左键单击 会将窗口提升到窗口堆栈的顶部; 中键单击 会移动窗口; 右键单击 会将窗口发送到窗口堆栈的底部。
Motif 使用三个按钮
- 最右侧 "Maximize" 按钮 (f.fullzoom):将窗口调整到显示器的全尺寸。
- 右侧内侧 "Minimize" 按钮 (f.iconify):将窗口图标化。
- 左侧 "Menu" 按钮 (f.menu "name_of_menu"):通常是针对窗口执行的操作的菜单。
此外,在 标题栏 或突出显示的区域 (f.move) 上 左键单击,拖动到屏幕上的新位置,然后释放会将窗口移动到该位置。
- 最右侧 "Close" 按钮 (f.delete 或 f.destroy 或 f.deletedestroy):关闭窗口。
- 右侧中间 "Maximize/Restore" 按钮 (f.fullzoom):将窗口调整到显示器的全尺寸。
- 右侧内侧 "Minimize" 按钮 (f.iconify):将窗口图标化。
- 左侧 "Menu" 按钮 (f.menu "name_of_menu"):通常是针对窗口执行的操作的菜单。
此外,在 标题栏 或突出显示的区域 (f.move) 上 左键单击,拖动到屏幕上的新位置,然后释放会将窗口移动到该位置。