在 XMonad 中渲染特定一侧的窗口边框

在 XMonad 中渲染特定一侧的窗口边框

XMobar 允许配置边框位置以及宽度:

{ border = BottomB
, borderColor = "#4F5B66"
, borderWidth = 1 }

我希望在 XMonad 中做同样的事情,但似乎边框只能通过以下属性进行配置:

{ borderWidth = 1
, normalBorderColor = "#4F5B66"
, focusedBorderColor = "#96B5B4" }

即使有了XMonad.Layout.NoBorders,这似乎也不是一种选择(或者不是一个简单的选择)。

最后,我希望有一个像素的底部边框,它总是被绘制并根据焦点改变颜色。目前这可能吗?我将如何进行这样的设置?

答案1

这个问题已经得到了充分的回答GitHub 问题在这个问题很少受到关注后我就打开了。

这样做的问题是 xmonad 不绘制自己的边界;它只是告诉 X 它们应该有多厚以及什么颜色。

[可以]告诉X对结构border_pixmap中的元素使用某些模式XSetWindowAttributes

如果您假设[中描述的]所有警告https://tronche.com/gui/x/xlib/window/attributes/border.html]实际上不存在或者没有任何意义,那么您可能会得出这样的结论:[...]可以通过指定一个围绕整个窗口的非常大的像素图来设置仅底部边框。

[就目前情况而言,]图形驱动程序编写者不断打破服务器端边界,因为现在只有 xmonad 和 dwm 使用它们。而且两者都没有使用 borderPixmap,因此可能隐藏着很多错误。

这里的要点是,虽然理论上应该可以使用窗口属性来实现此目的,但这不是一个好主意。有一种可能更好的替代方法:

要在 xmonad 中获得此结果,您需要具有宽度为 0 的边框,然后实现窗口装饰,在您想要“边框”的位置放置一个彩色条。

实际上,编写 DecorationStyle 类的实例非常容易,该实例将在窗口的一侧放置类似边框的装饰。如果该侧是顶部或底部,则栏将足够宽,并且窗口的标题文本将在其中呈现,但是可以通过将文本设置为与栏相同的颜色或提供空来解决这个问题字体。

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}

import qualified XMonad.StackSet as W
import XMonad.Layout.Decoration
import XMonad.Util.Types

data SideDecoration a = SideDecoration Direction2D
  deriving (Show, Read)

instance Eq a => DecorationStyle SideDecoration a where

  shrink b (Rectangle _ _ dw dh) (Rectangle x y w h)
    | SideDecoration U <- b = Rectangle x (y + fi dh) w (h - dh)
    | SideDecoration R <- b = Rectangle x y (w - dw) h
    | SideDecoration D <- b = Rectangle x y w (h - dh)
    | SideDecoration L <- b = Rectangle (x + fi dw) y (w - dw) h

  pureDecoration b dw dh _ st _ (win, Rectangle x y w h)
    | win `elem` W.integrate st && dw < w && dh < h = Just $ case b of
      SideDecoration U -> Rectangle x y w dh
      SideDecoration R -> Rectangle (x + fi (w - dw)) y dw h
      SideDecoration D -> Rectangle x (y + fi (h - dh)) w dh
      SideDecoration L -> Rectangle x y dw h
    | otherwise = Nothing

相关内容