如何浮动具有 WM_NAME 但没有 WM_CLASS 的窗口

如何浮动具有 WM_NAME 但没有 WM_CLASS 的窗口

配置

Debian Linux 8.2,64 位,Xmonad 0.11

当它开始的时候

我最近升级了我的系统(到 debian8),所以我必须对我的xmonad.hs配置进行一些调整 - 即更改 GStreamergst-launch窗口的管理钩子:

, title     =? "gst-launch-0.10" --> doFloat

到:

, title     =? "gst-launch-1.0" --> doFloat

我使用的title是而不是className因为gst-launch-1.0Windows 只有这个属性:

$ xprop
_NET_WM_DESKTOP(CARDINAL) = 6
WM_NAME(STRING) = "gst-launch-1.0"
WM_STATE(WM_STATE):
                window state: Normal
                icon window: 0x0
_MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x2, 0x0, 0x1, 0x0, 0x0
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW

它能做什么

我遇到了非常奇怪的行为,这是我在旧窗户上没有见过的gst-launch-0.10。当gst-launch-1.0窗口(通常很小 - 400x300)启动时,出现以下情况之一,概率递减:

  • 将窗口添加为另一个图块(根本不浮动)并拉伸其内容以填充此图块(保持纵横比),图块的其余部分为黑色
  • 将窗口添加为另一个图块(根本不浮动),但仅在此图块的左上角绘制(不拉伸),图块的其余部分显示 X-Window 背景
  • 正确浮动窗口的概率小于 10%

我尝试过的

doFullFloatdoCenterFloat做完全相同的事情(除了在最后一种情况下它是居中或完整的)

我怀疑什么

我很确定问题在于使用 onlyWM_NAME/title而不是 WM_CLASS/className/appName,因为标题可以在窗口的生命周期内更改。我认为该gst-launch-1.0窗口以其他(或没有)标题开始,一段时间后它会切换到gst-launch-1.0.那么能不能xmonad拿到正赛冠军或者决赛就只能看运气了gst-launch-1.0

问题

有没有办法在manageHook中“等待一段时间”,这样我就可以确保抓住最后一个窗口WM_NAME/title

或者还有其他想法吗?

附加信息:

显然这已经在 gstreamer 中修复了 -https://bugzilla.gnome.org/show_bug.cgi?id=750455- 但不幸的是我需要使用 debian 附带的 gstreamer。

答案1

这可能会有所帮助,以下是类型,X ()因此可以绑定到键绑定。

withWindowSet
  $ (\ws -> case W.stack . W.workspace . W.current $ ws of
      Just w' ->
        mapM_
            (\w -> do
              s <- withDisplay
                $ \d -> fmap resClass $ liftIO $ getClassHint d w
              case (s) of
                "Emacs" -> do
                  windows $ W.focusWindow w
                "Lxterminal" -> do
                  wmName <- withDisplay
                    $ \d -> getStringProperty d w "WM_NAME"
                  case wmName of
                    Just "ranger" -> windows $ W.focusWindow w
            )
          $ W.integrate w'
      _ -> return ()
    )

重要的几行是:

"Lxterminal" -> do
  wmName <- withDisplay $ \d -> getStringProperty d w "WM_NAME"
    case wmName of
      Just "ranger" -> windows $ W.focusWindow w

所以我们首先匹配 by WM_CLASS,然后WM_NAME.

相关内容