You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XMonad中生成与当前聚焦窗口位置匹配的浮动窗口?

最佳解决方案:直接传递几何参数给启动程序

你完全不用搞那些hack方法,利用urxvt的原生参数和Xmonad的按键绑定逻辑就能轻松实现:

  1. 在按键绑定中获取原窗口几何信息并传递给urxvt
    在keys列表里,通过withFocused拿到当前聚焦窗口的位置和尺寸,转成urxvt支持的-geometry参数格式,同时给新窗口设个独有的WM_NAME方便后续识别:
import XMonad
import Graphics.X11.Xlib.Types (Rectangle(..))
import Graphics.X11.Xlib.Window (getWindowAttributes)

-- 辅助函数:获取窗口的位置与尺寸
getWindowRect :: Window -> X Rectangle
getWindowRect w = do
  attrs <- io $ getWindowAttributes w
  return $ Rectangle { rect_x = wa_x attrs
                     , rect_y = wa_y attrs
                     , rect_width = wa_width attrs
                     , rect_height = wa_height attrs
                     }

myKeys conf = mkKeymap conf $
  [ ("M-c", withFocused $ \w -> do
      Rectangle x y w h <- getWindowRect w
      let geom = show w ++ "x" ++ show h ++ "+" ++ show x ++ "+" ++ show y
      spawn $ "urxvt -name FloatingClone -geometry " ++ geom)
  ]
  1. 在ManageHook中设置窗口为浮动
    只需要匹配刚才设置的WM_NAME,直接标记为浮动即可——因为urxvt已经通过-geometry参数把位置和尺寸都搞定了,不需要再在钩子中调整:
import XMonad.Hooks.ManageHelpers (doFloat)
import XMonad.Util.WindowProperties (title)

myManageHook = composeAll
  [ title =? "FloatingClone" --> doFloat
  ]

为什么这比你的方案更好?

  • 完全是原生功能结合,没有任何hack手段:既不用往WM_NAME里塞数据,也不需要依赖X属性或者MVar传递状态
  • 从根源上避免了焦点转移的问题:所有位置信息在启动新窗口时就已经传递给它了,后续钩子只需要负责窗口的浮动状态,根本不需要再依赖原聚焦窗口的信息

如果不想通过urxvt参数设置位置,另一个原生方案是扩展Xmonad的状态结构,把原窗口的几何数据存在自定义状态里,再在manageHook中读取。但这个方法需要修改Xmonad的State类型,复杂度更高,远不如上面的方案简洁。


内容的提问来源于stack exchange,提问作者John Z.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 23:52:05