适合程序员的桌面窗口管理方案

2022-03-15
教程

介绍下我在办公室使用的桌面窗口管理方案。

先说下硬件:我的工作电脑是一台 13 英寸的 Macbook Pro,外接了一个 27 英寸的显示器,使用了一个电脑支架把笔记本架起来了,这样两个显示器差不多是并排的样子。

然后看下我的窗口布局规划,可能会比较特殊一点,不过是经过精心考虑的。

桌面布局示意

右边的大显示器我按 1:2 分成两列,左边这一列是最大的显示空间,我把它当作“主空间”来使用,一般我在编码状态下会把编辑器放在这个位置,非编码状态下这里通常就是浏览器了。因为本来两个显示器的大小是不一样的,这样进行划分,主空间两侧的空间反而是比较均衡的状态了。显示器和电脑屏幕在桌子上的摆放也是非对称的,当我坐下时,正对着的是这个“主空间”的正中央,这样也避免一个常见问题:两个一样大的显示器对称排布时,正对着的位置恰好是两个显示器中间的缝,于是工作中几乎时刻是扭着头的,时间一长脖子就受不了了。

左边笔记本的屏幕没有做切分,这块空间一般在编码的时候放浏览器看文档资料,或者放个 Terminal 调试,也可以是另一份代码,使用完整的屏幕保证它总是够用的,不至于不得不把窗口拉大然后频繁切换窗口。

大显示器右边的 1/3 被一分为二,这两块空间主要用来放IM软件,包括飞书、Telegram、微信、QQ、Twitter桌面版……IM软件也平铺出来也是为了减少切换窗口,我只需要在干正事的时候时不时瞟一眼就行了,有需要关注的消息时再去处理。必要的时候这个小格也可以临时放一下 Terminal 之类的小窗口。

再说窗口管理软件方面,可能我的搞法比较变态,我也没找到合适的软件,最后使用的方案是 HammerSpoon 一点脚本,HammerSpoon 大体上就是 Mac 版的 AHK,功能是弱了很多,不过在窗口管理这一块还是完全够用的。我的脚本很简单,使用 4 个快捷键,分别把窗口移动到 4 个格子:

 1hs.hotkey.bind("cmd", "1", function()
 2    local sf = hs.screen.primaryScreen():frame()
 3    hs.window.focusedWindow():setFrame(hs.geometry.new(sf.x, sf.y, sf.w*2/3, sf.h))
 4end)
 5
 6hs.hotkey.bind("cmd", "2", function()
 7    hs.window.focusedWindow():setFrame(hs.screen.allScreens()[2]:frame())
 8end)
 9
10hs.hotkey.bind("cmd", "3", function()
11    local sf = hs.screen.primaryScreen():frame()
12    hs.window.focusedWindow():setFrame(hs.geometry.new(sf.x+sf.w*2/3, sf.y, sf.w/3, sf.h/2))
13end)
14
15hs.hotkey.bind("cmd", "4", function()
16    local sf = hs.screen.primaryScreen():frame()
17    hs.window.focusedWindow():setFrame(hs.geometry.new(sf.x+sf.w*2/3, sf.y+sf.h/2, sf.w/3, sf.h/2))
18end)

最后还有一个问题,就是我平时需要启动的 IM 太多了,虽然大部分消息都是不需要实时处理的,但是为了不错过重要消息,不得不隔一段时间手动检查一遍。解决这个问题我还是用 HammerSpoon 脚本,我会把各种不需要实时关心的IM窗口全扔到4号格子里,然后用脚本开个定时器,隔一段时间就把这一坨里在最下面的窗口给捞到最前面。3号窗口是固定不切换的,预留给比较重要的IM窗口,比如飞书。

这个切换窗口的 HammerSpoon 脚本也分享一下。Hammerspoon的lua引擎似乎有点问题,定时器跑一段时间就跑没了,所以干脆直接在每次触发后把脚本重载一下。

 1local myTimer = hs.timer.new(120, function()
 2    local sf = hs.screen.primaryScreen():frame()
 3    local windows = hs.window.orderedWindows()
 4    local bottom_win = nil
 5    for i, win in ipairs(windows) do
 6        local fm = win:frame()
 7        if math.abs(fm.x-(sf.x+sf.w*2/3))<1 and math.abs(fm.y-(sf.y+sf.h/2))<1 then
 8            if win:id() == hs.window.focusedWindow():id() then
 9                break
10            end
11            bottom_win = win
12        end
13    end
14    if bottom_win ~= nil then bottom_win:raise() end
15    hs.reload()
16end)
17myTimer:start()

欢迎加入技术讨论 QQ 群: 745157974

自动给 Gmail 中 GitHub 的邮件打标签

2020-01-15
教程 App Script

追踪 GitHub PR review 记录

使用 chrome 插件追踪 GitHub PR review 记录,并把数据存放在 Google Spreadsheet。
教程 App Script

使用 Docker+Seafile 搭建私有云存储

2015-05-10
教程