我将如何从 XMonad 中的所有 Floating windows 中删除边框

How would I remove borders from all Floating windows in XMonad

有几个类似的问题,但 none 完全解决了我的问题,例如 this 问题解释了如何从全屏浮动中删除边框 windows。

使用 XMonad.Layout.NoBorders 你可以做很多很酷的事情,比如删除某些 windows 的边框,或者如果它是唯一的 window 或唯一的全屏浮动 windows。

我找不到所有浮动 windows 的任何东西,但是如果有人能给我指出一些我可以用来检查 window 是否浮动的工具,我是当然我可以尝试破解一个解决方案。

欢迎提出任何建议

我将使用 XMonad.Layout.NoBorders 的 source code 作为参考,因为我找不到更合适的现有内容。我们想看看它是如何实现 "remove borders on fullscreen floating windows",看看它是否可以轻松地放宽到 "remove borders on floating windows"(没有全屏约束)。

根据您链接的问题的答案:

layoutHook = lessBorders OnlyFloat $ avoidStruts $ myLayout

OnlyFloat 似乎是 "remove borders on fullscreen floating windows" 的说明符,所以让我们检查一下它的定义:

data Ambiguity = Combine With Ambiguity Ambiguity
               | OnlyFloat
               | Never
               | EmptyScreen
               | OtherIndicated
               | Screen
    deriving (Read, Show)

它本身并没有多大帮助。我们应该看看其他地方,看看代码如何处理这些值。


可以肯定的是,第一个要检查的函数是 lessBorders:

lessBorders :: (SetsAmbiguous p, Read p, Show p, LayoutClass l a) =>
        p -> l a -> ModifiedLayout (ConfigurableBorder p) l a
lessBorders amb = ModifiedLayout (ConfigurableBorder amb [])

lessBorders的类型签名可以看出:

OnlyFloat :: (SetsAmbiguous p, Read p, Show p) => p

这是一个好兆头,因为它意味着 lessBorders 没有明确期望 Ambiguity:我们可以通过实现我们自己的 SetsAmbiguous 并将其传递给此处来扩展功能现有 lessBorders。现在让我们看看 SetsAmbiguousAmbiguity 的实现:

class SetsAmbiguous p where
    hiddens :: p -> WindowSet -> Maybe (W.Stack Window) -> [(Window, Rectangle)] -> [Window]

instance SetsAmbiguous Ambiguity where
    hiddens amb wset mst wrs
      | Combine Union a b <- amb = on union next a b
      | Combine Difference a b <- amb = on (\) next a b
      | Combine Intersection a b <- amb = on intersect next a b
      | otherwise = tiled ms ++ floating
      where next p = hiddens p wset mst wrs
            nonzerorect (Rectangle _ _ 0 0) = False
            nonzerorect _ = True
            screens =
              [ scr | scr <- W.screens wset,
                      case amb of
                            Never -> True
                            _ -> not $ null $ integrate scr,
                      nonzerorect . screenRect $ W.screenDetail scr]
            floating = [ w |
                        (w, W.RationalRect px py wx wy) <- M.toList . W.floating $ wset,
                        px <= 0, py <= 0,
                        wx + px >= 1, wy + py >= 1]
            ms = filter (`elem` W.integrate' mst) $ map fst wrs
            tiled [w]
              | Screen <- amb = [w]
              | OnlyFloat <- amb = []
              | OtherIndicated <- amb
              , let nonF = map integrate $ W.current wset : W.visible wset
              , length (concat nonF) > length wrs
              , singleton $ filter (1==) $ map length nonF = [w]
              | singleton screens = [w]
            tiled _ = []
            integrate y = W.integrate' . W.stack $ W.workspace y

hiddens 是我们需要实现的唯一方法。它的参数是我们的 SetsAmbiguous 值、一个 WindowSet 和其他一些东西,它 returns 一个不应显示边框的 windows 列表。组合操作和其他 Ambiguity 值有很多逻辑,但现在这些对我们来说并不重要。我们关心的是这个片段:

            floating = [ w |
                        (w, W.RationalRect px py wx wy) <- M.toList . W.floating $ wset,
                        px <= 0, py <= 0,
                        wx + px >= 1, wy + py >= 1]

这很有前途。它通过从 WindowSetfloating 部分中提取所有 windows 来定义一组浮动 windows,将其转换为列表(最初它是一个 Data.Map) , 并过滤掉所有未覆盖整个屏幕的 windows 。我们需要做的就是移除过滤器。


进行更改并删除所有与平铺 windows 和设置操作相关的不必要代码(这是大部分实现),我们最终得到的只是:

import XMonad.Layout.NoBorders
import qualified XMonad.StackSet as W
import qualified Data.Map as M

data AllFloats = AllFloats deriving (Read, Show)

instance SetsAmbiguous AllFloats where
    hiddens _ wset _ _ = M.keys $ W.floating wset

然后我们可以说:

layoutHook = lessBorders AllFloats $ myLayout...