最近用 i3 实现了一个在我脑中转了很久的念头――对换两个显示器上的工作区。比如:Firefox 在笔记本显示器上,Emacs 在外接显示器上,按一个快捷键,将 Emacs 放到笔记本显示器上,将 Firefox 放到外接显示器上。
1 配置
- 确保安装了 i3 和 python2.7
- 学会 i3 的基本操作和配置方法:http://i3wm.org/docs/userguide.html
- 安装 i3-py:
sudo pip install i3-py
- 下载脚本: swap-workspace.py
- 给 swap-workspace.py 执行权限:
chmod a+x swap-workspace
- 在 i3 的配置文件(/home/yourname/.i3/config)里添加:
# swap workspaces bindsym $mod+Shift+s exec /path/to/i3-scripts/swap-workspace.py
- 重新加载 i3:
Mod+Shift+r
(Mod 是什么可以自己设定,我用的是 Windows 键) - 按
Mod+Shift+s
对换两个显示器上的工作区
2 HACK 记录
看到陈斌的一个 知乎回答 之后,我决定试一下 i3 ―― 颇为知名的 Linux 桌面管理器。稍微过了一下 官网教程 (基本只看了第一节,即 Default keybindings )就上手了,简单实用。
熟悉了一天之后,突然心血来潮,想要实现 “对换两个显示器上的工作区” 这个功能。Google 一下之后,发现官方的文档里有一篇是讲这个的: http://i3wm.org/docs/user-contributed/swapping-workspaces.html
根据文章,把以下代码保存到 swap-workspace.py :
#!/usr/bin/python2.7 import i3 outputs = i3.get_outputs() # set current workspace to output 0 i3.workspace(outputs[0]['current_workspace']) # ..and move it to the other output. # outputs wrap, so the right of the right is left ;) i3.command('move', 'workspace to output right') # rinse and repeat i3.workspace(outputs[1]['current_workspace']) i3.command('move', 'workspace to output right')
运行之,不好使,返回以下错误:
Traceback (most recent call last): File "swap-workspace.py", line 14, in <module> i3.workspace(outputs[1]['current_workspace']) File "/usr/local/lib/python2.7/dist-packages/i3.py", line 404, in function msg_full = ' '.join([message] + list(args) + list(args2)) TypeError: sequence item 1: expected string, NoneType found
仔细读了代码,然后开 python 的 REPL 实验了一下,发现在我的电脑上, outputs 有四个(而不是两个):
>>> import i3 >>> outputs = i3.get_outputs() >>> outputs [{u'active': True, u'current_workspace': u'4', u'name': u'LVDS1', u'rect': {u'y': 0, u'x': 0, u'height': 768, u'width': 1360}, u'primary': True}, {u'active': False, u'current_workspace': None, u'name': u'VGA1', u'rect': {u'y': 0, u'x': 0, u'height': 0, u'width': 0}, u'primary': False}, {u'active': True, u'current_workspace': u'2', u'name': u'HDMI1', u'rect': {u'y': 0, u'x': 1360, u'height': 1080, u'width': 1920}, u'primary': False}, {u'active': False, u'current_workspace': None, u'name': u'DP1', u'rect': {u'y': 0, u'x': 0, u'height': 0, u'width': 0}, u'primary': False}] >>> len(outputs) 4
根据这些信息,修改代码如下:
for output in i3.get_outputs(): if output['active']: i3.workspace(output['current_workspace']) i3.command('move', 'workspace to output right')
试了一下,可以用了!
但是这样写的话,一旦遇到三屏(或更多),就会出错,还是限定脚本只能用于双屏吧:
#!/usr/bin/python2.7 # Swap workspaces on two monitors import i3 # collect active outputs to_be_swapped = [output for output in i3.get_outputs() if output['active']] # only swap when there are two active outputs if len(to_be_swapped) == 2: for output in to_be_swapped: i3.workspace(output['current_workspace']) i3.command('move', 'workspace to output right')
觉得自己以后还会写 i3 的脚本,于是建了个 Github repo: https://github.com/RenWenshan/i3-scripts