1

目标

在 Xmonad 中为特定窗口设置无边框。

具体例子:我想要firefox并且feh 总是没有边界。我不仅要为特定布局(例如,单个窗口)或特定窗口模式(如浮动)设置它。

尝试A

我最直接的想法是在 中添加一行manageHook,它应该处理窗口创建。所以我在我的自定义中放了一行ManageHook

className =? "firefox" --> ask >>= \w -> liftX $ withDisplay $ \d -> io $ setWindowBorderWidth d w 0 >> idHook

它编译,但不幸的是,当我开始时没有任何反应firefox

然后我尝试调试它:

  1. 测试了以下,它可以工作(新的firefox窗口浮动),这表明我的自定义ManageHook工作,我的逻辑(修改窗口后跟idHook)应该是可以的。
className =? "firefox" --> ask >>= liftX . float >> idHook
  1. 通过在XMonad.Actions.NoBorders中尝试测试setWindowBorderWidth功能。做类似的事情。我使用了一个键绑定来调用它并且它有效。因此在创建窗口后的 Xmonad 会话期间运行良好。toggleBordertoggleBordersetWindowBorderWidthtoggleBordersetWindowBorderWidth

  2. 测试了以下内容(在此处找到)但它不起作用,与我的代码相同(尝试 A)。

className =? "firefox" --> ask >>= liftX . toggleBorder >> idHook

尝试 B

我在XMonad.Layout.NoBorders这个答案hasBorder中找到了这个函数,但我没有成功。

如果我只放入className =? "firefox" --> hasBorder FalseManageHook不使用layoutHook,则不会发生任何事情。我查看了源代码hasBorder发现它只广播了一条消息,但没有设置边框。我想我可能需要调用layoutHookfromXMonad.Layout.NoBorders来真正设置边界,但我不确定应该使用哪一个。而且我也不确定是否需要指定要使用的任何布局XMonad.Layout.NoBorders

问题

  1. Xmonad 是否设置了边界,ManageHook所以我在尝试 A 中的代码无效?

  2. 如果 Q1 为真,这是否意味着在屏幕上绘制窗口时我只能在LayoutHook(可能使用)处不设置边框?XMonad.Layout.NoBorders

  3. 如果 Q2 为真,我是否需要指定布局以及layoutHook可以使用的布局?

4

2 回答 2

1

我会尝试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) [] ||| ...

注意:这只会影响重新编译和重新启动 XMonad后创建的窗口。在关闭并重新启动之前,已经存在的 firefox 和 feh 实例仍然有它们的边界。

于 2021-10-29T09:01:37.927 回答
0

我想我找到了我的问题的答案。

Xmonad 是否在 ManageHook 之后设置边框,因此我在尝试 A 中的代码无效?

是的。

看起来 xmonad 窗口初始化逻辑在XMonad/Operations.hs中。当一个窗口被创建时,函数manage()被调用。函数的最后三行:

  1. 负载ManageHook
  2. 申请ManageHook, runQuery()_
  3. 运行windows()函数,该函数从 config 加载边框信息并应用setInitialProperties()函数根据边框配置设置边框

最后一步setInitialProperties()调用setWindowBorderWidth()从配置加载的边框宽度,这使 mysetWindowBorderWidth()作为一个ManageHook步骤无效。

如果我不在XMonad/Operations.hs中更改此逻辑,看起来我只能使用尝试 B。但是,我真的觉得windows跳转问题很烦人。这不仅发生在Full布局中,我使用Tall的是单个窗口。当我在两个工作区之间切换时,这两个工作区都有一个没有边框的窗口,我看到了这个跳跃。视觉效果会影响屏幕上的所有像素,因为它需要缩放整个窗口。

如果 Q1 为真,是否意味着在屏幕上绘制窗口时我只能在 LayoutHook 上设置无边框(可能使用 XMonad.Layout.NoBorders)?

不,除此之外的另一种可能性LayoutHooklogHook

如果 Q2 为真,我是否需要指定布局以及我可以使用哪个 layoutHook?

是的。但是,如果logHook使用,则无需覆盖默认布局。

解决方案

让我们建立一个新的 XMonad 扩展来实现人们在 12 年前提出的这个功能。

于 2021-10-29T21:28:27.787 回答