什么是窗口管理器
窗口管理器 (Window Manager) 就是用来管理窗口的. 主要分为两大类:
Stacking WM:
每个窗口都可以拖拽, 改变大小, 窗口之间可以有重叠, 主要靠鼠标控制.
比如下图, Stacking WM的屏幕利用率比较低, 而且操作严重依赖鼠标, 比较慢.
Tiling WM:
窗口不能拖拽, 窗口之间没有重叠, 像瓷砖一样铺满屏幕, 配合很多快捷键使用, 基本不或
者少依赖鼠标进行控制.
- 自动放置窗口, 不重叠, 空间利用率高
- 多种布局方式切换, 适应各种需求 (基本所有tiling wm都不止Tiling一种布局, 比如i3wm还有Tabbed, Stacked, 还可以选择让某窗口全屏或是悬浮)
- 基本全靠键盘控制, 快速方便
container与tree
大多窗口管理器采用树结构来保存窗口, i3也是如此.
每个workspace的所有窗口保存在一个tree数据结构里面, 这个tree的每个节点都是一个 container (window算特殊的container, 是没有孩子的叶子节点), 一个container里面又可以包含多个container.
container属性
每个container有两个比较重要的属性:
布局方式
split (分splith, splitv), tabbed 或者 stacked
图 1 代表的窗口可能是图 2, 也可能是图 3或者其他的, 因为我们不知道每个container内部的窗口布局方式. 所以窗口管理器会为每个节点保存布局方式, 表示内部的孩子节点应该按照什么方式放置.
所以如果想只代表图 2 中的窗口, 那么应该为container增加布局方式属性, 如图 1 所示.
split方向对应占多少百分比
因为我们通常还会控制每个窗口/容器的宽度/高度, 所以还应该为每个容器增加split方向的空间占比, 如图 5 所示.
练习与理解
为了理解我们在操作窗口时对应tree的构造, 我们将窗口/容器都放在另一个设为tabbed或
者stacked布局的容器内 – 因为这两种布局才会显示标题.
- 切换到一个没有任何窗口的workspace: 如
$Mod+3
. - 用
$Mod+e
设置默认的布局为split(水平/垂直), (一般不会设为tabbed或stacked). $Mod+ENTER
打开一个terminal (我这里是st, 或者任何别的窗口也行).$Mod+w/s
设置所在container布局为tabbed或stacked$Mod+v/V
新建一个垂直/水平split布局的container包裹当前的st窗口- 在节点(container或window)所在container只有一个窗口, 且container布局方式为水平/垂直split时,
$Mod+v/V
只会切换split方向 - 当节点所在container不止一个窗口, 或者container布局方式为tabbed或者stacked时,
$Mod+v/V
会创建一个新的垂直/水平split布局的container包裹当前节点
- 在节点(container或window)所在container只有一个窗口, 且container布局方式为水平/垂直split时,
- 后续在这个stabbed或者stacked container下操作就可以看到标题了
当前看到标题应该为 V[st]
, 再 $Mod+ENTER
之后显示为 V[st st]
.
Tips:
使用 $Mod+c
或者 $Mod+p
来选择孩子或父亲节点窗口, 然后对该节点进行操作:
- 创建一个兄弟节点
- 删除/关闭节点窗口 (节点下所有窗口都会被关闭)
- 移动节点窗口
- 修改节点窗口大小
快捷键设置
这里仅列出了比较重要的快捷键, 我详细的配置放在了github的.dotfiles仓库.
|
|
- Mod-h/j/k/l
- 切换到左/上/下/右边窗口
- Mod-S-h/j/k/l
- 移动窗口/容器
- Mod-y/u/i/o
- 调整窗口/容器大小
- Mod-v
- 增加一个container 存放当前focused window(或者container), 容器内采用垂直split布局
- Mod-S-v
- 同上, 不过容器内采用水平split布局
- Mod-e/w/s
- 设置 所在container 的布局为Split(会在splith, splitv间循环), Tabbed, Stacked
- Mod-p
- Focus parent
- Mod-c
- Focus child