如何在Haskell订阅X11活动?

ohfgkhjo  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(138)

我尝试在Haskell中使用XMonad's X11 library来模仿this Python solution,但不幸的是,当我通过切换焦点窗口来触发事件时,我的代码只是挂起,没有React:

disp <- X11.openDisplay ""
let root = X11.defaultRootWindow disp
X11.allocaSetWindowAttributes $ \swaPtr ->
    X11.changeWindowAttributes disp root X11.propertyChangeMask swaPtr
allocaXEvent $ \e -> nextEvent disp e

这段代码永远不会终止,但是Python的等价物通常会捕获X事件。

nvbavucw

nvbavucw1#

与您链接的python代码不同,XMonad的Haskell X11库非常接近C库,我们在这里要做的是:

  • 调用changeWindowAttributes,指定我们要更改的属性。这里我们要指定"event mask"属性。
  • 在调用之前,使用set_event_mask :: Ptr SetWindowAttributes -> EventMask -> IO ()swaPtr中写入我们要设置的实际事件掩码。

最终代码应如下所示:

X11.allocaSetWindowAttributes $ \swaPtr ->
    X11.set_event_mask swaPtr X11.propertyChangeMask
    X11.changeWindowAttributes disp root X11.cWEventMask swaPtr

稍微离题:非常不幸的是,X11.propertyChangeMaskX11.cWEventMask在C中具有相同的类型,而且在Haskell中也具有相同的类型。这里的newtype Package 器将阻止您的原始代码,该代码试图将事件掩码作为属性掩码传递。可以说,即使在C语言中,人们也会使用轻量级的struct EventMask { unsigned long em; }来防止类似类型的混淆。(我不明白),C库经常放弃将结构体作为参数传递,好像它们仍然希望与前ISO、前ANSI、K & R C兼容,即使它们是在更现代的时代创建的。

相关问题