基于 REFLECTX 切换 Shrink 和 Expand

Switch Shrink and Expand based on REFLECTX

我正在使用 XMonad.Layout.Reflect 和 XMonad.Layout.MultiToggle 在需要时左右翻转我的布局。但是,当反映任何布局时,我的键绑定用于缩小和扩展布局,例如。

...

((modm,  xK_h), sendMessage Shrink),
((modm,  xK_l), sendMessage Expand),

...

的行为与它们相反。

所以,我想要的是一种重新映射我的键的方法,或者可能使用一个函数而不是 sendMessage 以某种方式检测布局状态并根据该状态选择 Shrink/Expand。

现在我知道检查例如。全局状态变量(我猜其中没有这样的东西)不是很 Haskelly,所以我对如何做到这一点有点不知所措。我考虑过 XMonad.Actions.PerWorkspaceKeys,但它似乎与整个工作区名称匹配。另一条路线可能是在 defaultConfig 中使用 add/delete 键绑定,但同样 - 我不确定这是否可行(反正看起来很乱)。

有任何关于如何解决这个问题的想法吗?我知道 Haskell 的水平是从头到尾阅读了 "Learn you a Haskell..." 这本书,并以此为基础制作了一些小程序。

一种方法是使用布局描述来确定它是否已被反映,如下 this blog post by Thomas Churchman:

import qualified XMonad.StackSet as S
import Data.List (isInfixOf)

getActiveLayoutDescription :: X String
getActiveLayoutDescription = do
    workspaces <- gets windowset
    return $ description . S.layout . S.workspace . S.current $ workspaces

键绑定将如下所示:

((modm,  xK_h), do
    layoutDesc <- getActiveLayoutDescription
    if "ReflectX" `isInfixOf` layoutDesc
        then sendMessage Expand
        else sendMessage Shrink
,
((modm,  xK_l), do
    layoutDesc <- getActiveLayoutDescription
    if "ReflectX" `isInfixOf` layoutDesc
        then sendMessage Shrink
        else sendMessage Expand
    ),

旁注:

my keybinds for shrinking and expanding the layout [...] behaves as they are inversed.

虽然您想要做的事情很有意义,但值得一提的是,之所以会发生这种行为,是因为反映布局也会反映主窗格的位置。由于 ShrinkExpand 作用于主面板,如果您使用像 Tall 这样的布局,就绝对水平坐标而言,它们看起来是倒置的,其中主面板窗格位于屏幕左侧。不同的布局可能会受到不同的影响。

Now I know that checking eg. global state variables (of which there are no such thing I guess) is not very Haskelly, so I am at a little bit of a loss on how to do this.

这种方法并非不可想象,XMonad.Util.ExtensibleState就是为了设置这种东西。不过,在这种情况下,我觉得使用有状态标志麻烦多于它的价值。