如何重新启动沙盒和自定义编译的Xmonad

时间:2016-06-29 14:28:53

标签: haskell xmonad

我希望通过xmonad.hsstack扩展到自己的沙盒项目环境中来扩展我的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 sendRestartxmonad - 似乎都不起作用。当我关闭我的Xserver并手动重启时,会显示任何和所有更新,但是现在热插拔更改似乎无法正常工作。是否需要同时看到两个单独的二进制文件 - 当前的新二进制文件?

编辑:通过阅读xmonad-entryhelperX11sendRestart :: 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的系统安装而不是我的沙箱(当前符号链接到二进制文件)编译和启动时返回由堆栈生成。

1 个答案:

答案 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并从现在开始调用它。