目标
为Xmonad中的特定窗口设置无边框。
具体的例子:我希望firefox
和feh
总是没有边界。我想设置这个不仅为特定的布局(例如,单窗口)或特定的窗口模式,如浮动。
尝试
我最直接的想法是在manageHook
中添加一行,该行假定用于处理窗口创建。因此,我在自定义的ManageHook
中添加了一行:
className =? "firefox" --> ask >>= w -> liftX $ withDisplay $ d -> io $ setWindowBorderWidth d w 0 >> idHook
它可以编译,但不幸的是,当我启动firefox
时什么也没有发生。
然后我试着调试它:
- 测试了下面的工作(新的firefox窗口是浮动的),这表明我的自定义
ManageHook
工作,我的逻辑(修改窗口之后的idHook
)应该是OK的。
className =? "firefox" --> ask >>= liftX . float >> idHook
通过在XMonad.Actions.NoBorders中尝试
toggleBorder
来测试setWindowBorderWidth
功能。toggleBorder
调用setWindowBorderWidth
做类似的事情。我使用一个键绑定来调用toggleBorder
,它工作。因此,setWindowBorderWidth
在创建窗口后的Xmonad会话期间工作得很好。测试了以下内容(在这里找到),但它不起作用,与我的代码(尝试A)相同。
className =? "firefox" --> ask >>= liftX . toggleBorder >> idHook
尝试B
我在XMonad.Layout.NoBorders和这个答案中找到了hasBorder
函数,但我没有成功。
如果我只把className =? "firefox" --> hasBorder False
放在ManageHook
而不使用layoutHook
,什么也不会发生。我检查了hasBorder
的源代码,发现它只广播消息而不设置边界。我想我可能需要从XMonad.Layout.NoBorders
调用layoutHook
来真正设置边界,但我不确定我应该使用哪一个。我也不确定我是否需要指定任何布局使用XMonad.Layout.NoBorders
。
Xmonad设置边界后ManageHook
,所以我的代码在尝试A无效?
如果Q1为真,是否意味着当窗口绘制在屏幕上时,我只能在LayoutHook
(可能使用XMonad.Layout.NoBorders
)设置无边界?
如果Q2为真,我需要指定一个布局和哪个layoutHook
我可以使用?
Xmonad设置边界后ManageHook
,所以我的代码在尝试A无效?
如果Q1为真,是否意味着当窗口绘制在屏幕上时,我只能在LayoutHook
(可能使用XMonad.Layout.NoBorders
)设置无边界?
如果Q2为真,我需要指定一个布局和哪个layoutHook
我可以使用?
我选择尝试B:
从xmonad-contrib:
导入NoBorders模块import XMonad.Layout.NoBorders
在manageHook中定义约束:
className =? "feh" --> hasBorder False
className =? "firefox" --> hasBorder False
并应用模块的布局修饰符之一,例如smartBorders
到所有查看你的布局:
layoutHook = smartBorders $ Full ||| ResizableTall 1 (3/100) (1/2) [] ||| ...
注意:这只会影响在之后创建的的windows重新编译并重新启动XMonad。已经存在的firefox和feh实例在关闭并重新启动之前仍然会有它们的边框。
我想我找到了问题的答案。
Xmonad是否在ManageHook之后设置边界,因此我在尝试A中的代码无效?
是的。
看起来像xmonad窗口初始化逻辑在xmonad/Operations.hs。创建窗口时,调用manage()函数。函数的最后三行:
- load
ManageHook
, - 应用
ManageHook
与runQuery()
, - 运行windows()函数,从配置中加载边界信息,并应用setInitialProperties()函数根据边界配置设置边界。
最后一步setInitialProperties()
调用setWindowBorderWidth()
的边界宽度从配置加载,这使我的setWindowBorderWidth()
作为ManageHook
步骤无效。
如果我不改变这个逻辑在XMonad/操作。是的,看起来我只能尝试b。然而,我真的发现窗口跳跃问题很烦人。这不仅发生在Full
布局中,我使用Tall
与单个窗口。当我在两个工作区之间切换时,这两个工作区都有一个没有边框的窗口,我看到这个跳跃。视觉效果会影响屏幕上的所有像素,因为它需要缩放整个窗口。
如果Q1是真的,这是否意味着当窗口绘制在屏幕上时,我只能在LayoutHook(可能使用XMonad.Layout.NoBorders)设置没有边界?
。除了LayoutHook
,还有一个可能是logHook
。
如果Q2为真,我是否需要指定一个布局和哪个layoutHook我可以使用?
是的。但是,如果使用logHook
,则不需要覆盖默认布局。
解决方案
让我们建立一个新的XMonad扩展来实现这个人们在12年前就要求的功能。