我希望通过xmonad.hs
将stack
扩展到自己的沙盒项目环境中来扩展我的main
。事实证明,通过将xmonad main
函数嵌入到使用xmonad-entryhelper的父xmonad.hs
中,可以实现这种沙盒化。按照README项目中的说明,从此转换main :: IO ()
main = do
statBar <- spawnPipe myXMobar
xmonad def
{ terminal = myTerminal
, focusFollowsMouse = myFocusFollowsMouse
, borderWidth = myBorderWidth
, modMask = myModMask
, workspaces = myWorkspaces
, normalBorderColor = myNormalBorderColor
, focusedBorderColor = myFocusedBorderColor
-- key bindings
, keys = myKeys
--, mouseBindings = myMouseBindings
-- hooks, layouts
, layoutHook = myLayoutHook
, manageHook = manageHook def <+> myManageHook
--, handleEventHook = myEventHook
, logHook = myLogHook statBar >> setWMName "LG3D"
--, startupHook = myStartupHook
}
:
kaleidoscope :: IO ()
kaleidoscope = do
statBar <- spawnPipe myXMobar
xmonad def
{ terminal = myTerminal
, focusFollowsMouse = myFocusFollowsMouse
, borderWidth = myBorderWidth
, modMask = myModMask
, workspaces = myWorkspaces
, normalBorderColor = myNormalBorderColor
, focusedBorderColor = myFocusedBorderColor
-- key bindings
, keys = myKeys
--, mouseBindings = myMouseBindings
-- hooks, layouts
, layoutHook = myLayoutHook
, manageHook = manageHook def <+> myManageHook
--, handleEventHook = myEventHook
, logHook = myLogHook statBar >> setWMName "LG3D"
--, startupHook = myStartupHook
}
main :: IO ()
main = EH.withCustomHelper kaleidoscopeConfig
where
kaleidoscopeConfig = EH.defaultConfig
{ EH.run = kaleidoscope
, EH.compile = \force -> EH.withLock ExitSuccess $ do
let cmd =
if force
then "cd /home/oldmanmike/src/github.com/oldmanmike/kaleidoscope && stack clean && stack build"
else "cd /home/oldmanmike/src/github.com/oldmanmike/kaleidoscope && stack build"
EH.compileUsingShell cmd
, EH.postCompile = EH.defaultPostCompile
}
要...
xmonad --recompile
所以,我现在可以使用.xmonad
编译我的项目,并且xmonad --restart
中找到的二进制文件与我的沙盒项目生成的二进制文件软链接。
但由于某种原因,xmonad --restart
已不再适用了。什么可能绊倒?
命令本身似乎不会从X产生任何错误 - 它只是成功返回,甚至没有任何迹象发生。我在shell中尝试mod-q
命令并将xmonad中的spawnPipe "xmonad --restart"
绑定到io sendRestart
或xmonad
- 似乎都不起作用。当我关闭我的Xserver并手动重启时,会显示任何和所有更新,但是现在热插拔更改似乎无法正常工作。是否需要同时看到两个单独的二进制文件 - 当前的新二进制文件?
编辑:通过阅读xmonad-entryhelper
,X11
和sendRestart :: IO ()
sendRestart = do
dpy <- openDisplay ""
rw <- rootWindow dpy $ defaultScreen dpy
xmonad_restart <- internAtom dpy "XMONAD_RESTART" False
allocaXEvent $ \e -> do
setEventType e clientMessage
setClientMessageEvent e rw xmonad_restart 32 0 currentTime
sendEvent dpy rw False structureNotifyMask e
sync dpy False
的源代码,我一直在解决这个问题。我现在正在分开这个:
internAtom
我还不熟悉X11 API,但令我感到奇怪的是handle e@ClientMessageEvent { ev_message_type = mt } = do
a <- getAtom "XMONAD_RESTART"
if (mt == a)
then restart "xmonad" True
else broadcastMessage e
handle e = broadcastMessage e -- trace (eventName e) -- ignoring
函数以及XMONAD_RESTART在客户端消息中的用途。还有这个处理程序:
restart :: String -> Bool -> X ()
restart prog resume = do
broadcastMessage ReleaseResources
io . flush =<< asks display
let wsData = show . W.mapLayout show . windowset
maybeShow (t, Right (PersistentExtension ext)) = Just (t, show ext)
maybeShow (t, Left str) = Just (t, str)
maybeShow _ = Nothing
extState = return . show . catMaybes . map maybeShow . M.toList . extensibleState
args <- if resume then gets (\s -> "--resume":wsData s:extState s) else return []
catchIO (executeFile prog True args Nothing)
所以我猜测原子只是用于ID消息事件的临时字符串? 当我运行重启时,我没有收到任何错误消息,所以看起来好像它一直到操作句柄:
xmonad-x86_64-linux
我怀疑这里有一个权限问题,{{1}}在由xmonad的系统安装而不是我的沙箱(当前符号链接到二进制文件)编译和启动时返回由堆栈生成。
答案 0 :(得分:2)
事实证明问题是我无法使用堆栈生成的xmonad
二进制文件,即使它在我的路径中并且~/.xmonad/xmonad-x86_64-linux
符号链接到它。相反,我通过将我的mod-q绑定到以下内容来重新启动工作:
restart "/home/oldmanmike/.xmonad/xmonad-x86_64-linux" True
只要我给它绝对路径,它就会起作用。
这是有道理的,因为先前观察到将以下内容放入我的.xinitrc会导致X崩溃:
exec xmonad
相反,我必须使用以下内容进行首次发布:
exec ~/.xmonad/xmonad-x86_64-linux
所以现在,看起来好像调用xmonad
对命令的可靠性要低得多,我应该将路径别名为xmonad-x86_64-linux
并从现在开始调用它。