如何在XMonad中生成与当前聚焦窗口位置匹配的浮动窗口?
最佳解决方案:直接传递几何参数给启动程序
你完全不用搞那些hack方法,利用urxvt的原生参数和Xmonad的按键绑定逻辑就能轻松实现:
- 在按键绑定中获取原窗口几何信息并传递给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) ]
- 在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.
相关产品推荐
相关产品推荐

