如何为AwesomeWM配置含固定三列的静态布局专属标签?
实现AwesomeWM静态三列专属标签的方案
嘿,这个需求完全能搞定,而且不用费劲写自定义布局——咱们结合AwesomeWM的规则、固定位置设置和专属标签就能完美实现你要的静态三列效果,下面一步步来:
核心思路
因为你要的是静态位置、不自动重排、空位保留,所以不能用默认的动态 tile 布局。我们的方案是:
- 创建一个专属标签,强制使用浮动布局(浮动布局不会自动调整窗口位置)
- 给三个目标应用分别绑定固定的几何位置(左/中/右各占1/3屏幕)
- 禁止在这个标签上切换布局,避免意外打乱排列
步骤1:创建专属静态标签
在你创建标签的代码段里,添加这个专属标签,指定布局为浮动,同时可以设置间隙(如果不需要就设为0):
-- 假设你在tags初始化的部分添加这段 local my_static_tag = awful.tag.add("StaticApps", { layout = awful.layout.suit.floating, -- 强制浮动布局 gap = 0, -- 窗口间的间隙,按需调整 gap_single_client = false, -- 单个窗口时也不自动占满 })
步骤2:给应用绑定固定位置的规则
用awful.rules.rules给每个目标应用设置规则:指定它们只能在专属标签打开,强制浮动,并且通过回调函数固定位置和大小。
提示:用
xprop工具可以查应用的class(终端输入xprop后点击目标窗口,看WM_CLASS的值)
awful.rules.rules = { -- 先保留你原有的其他规则... -- 应用A:占左侧1/3屏幕 { rule = { class = "AppA" }, -- 替换成你实际的应用class properties = { tag = my_static_tag, floating = true, maximized = false, -- 禁止窗口最大化 sticky = false, }, callback = function(c) local screen_geo = c.screen.geometry -- 获取当前屏幕的尺寸 -- 强制左侧定位,宽度设为屏幕1/3,高度占满 awful.placement.left(c, { margins = { top = 0, bottom = 0, left = 0 }, honor_workarea = true, -- 尊重屏幕的工作区(比如顶部状态栏) parent = screen_geo, }) c.width = screen_geo.width / 3 c.height = screen_geo.height end }, -- 应用B:占中间1/3屏幕 { rule = { class = "AppB" }, properties = { tag = my_static_tag, floating = true, maximized = false, sticky = false, }, callback = function(c) local screen_geo = c.screen.geometry -- 计算中间位置的X坐标,直接设置窗口的位置和大小 c.x = screen_geo.x + screen_geo.width / 3 c.y = screen_geo.y c.width = screen_geo.width / 3 c.height = screen_geo.height end }, -- 应用C:占右侧1/3屏幕 { rule = { class = "AppC" }, properties = { tag = my_static_tag, floating = true, maximized = false, sticky = false, }, callback = function(c) local screen_geo = c.screen.geometry c.x = screen_geo.x + (screen_geo.width / 3) * 2 c.y = screen_geo.y c.width = screen_geo.width / 3 c.height = screen_geo.height end }, }
步骤3:禁止标签的布局切换
为了防止误操作切换布局打乱静态排列,修改你的布局切换快捷键,让它跳过这个专属标签:
-- 假设你原来的布局切换快捷键是这样的,修改成: awful.key({ modkey }, "space", function () -- 只在非静态标签切换布局 if awful.tag.selected() ~= my_static_tag then awful.layout.inc(1) end end, {description = "select next layout", group = "layout"}), -- 同理,反向切换布局的快捷键也做同样处理 awful.key({ modkey, "Shift" }, "space", function () if awful.tag.selected() ~= my_static_tag then awful.layout.inc(-1) end end, {description = "select previous layout", group = "layout"}),
额外优化:重置窗口位置
如果不小心拖动了窗口,可以加一个快捷键让它回到原位:
-- 绑定Mod+Shift+R重置当前窗口位置(仅针对静态标签的应用) awful.key({ modkey, "Shift" }, "r", function (c) if c.tag ~= my_static_tag then return end -- 非静态标签不处理 local screen_geo = c.screen.geometry if c.class == "AppA" then awful.placement.left(c, { margins = {top=0, bottom=0, left=0}, parent=screen_geo }) c.width = screen_geo.width / 3 c.height = screen_geo.height elseif c.class == "AppB" then c.x = screen_geo.x + screen_geo.width / 3 c.y = screen_geo.y c.width = screen_geo.width / 3 c.height = screen_geo.height elseif c.class == "AppC" then c.x = screen_geo.x + (screen_geo.width / 3)*2 c.y = screen_geo.y c.width = screen_geo.width / 3 c.height = screen_geo.height end end, {description = "reset static app position", group = "client"}),
关于自定义布局的疑问
其实完全不需要自定义布局!上面的方案已经能完美满足你的需求:
- 每个应用固定在自己的列,焦点切换不会触发布局重排(因为浮动布局本身不会自动调整窗口)
- 某个应用未运行时,对应的位置会保持空置,不会被其他窗口占用
- 实现起来比写自定义布局简单得多,也更容易维护
内容的提问来源于stack exchange,提问作者0x2207
相关产品推荐
相关产品推荐

