【问题标题】:How to restart a sandboxed and custom-compiled Xmonad如何重新启动沙盒和自定义编译的 Xmonad
【发布时间】:2016-06-29 14:28:52
【问题描述】:

我想通过stack 将我的xmonad.hs 移动到它自己的沙盒项目环境中来扩展我的xmonad.hs。事实证明,通过将 xmonad main 函数嵌入到使用 xmonad-entryhelper 的父 main 中,可以实现这种沙盒。按照项目 README 中的说明,将 xmonad.hs 从这里转换为:

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 不再起作用。什么可能会绊倒它?

该命令本身似乎不会从 X 中产生任何错误 - 它只是成功返回,没有任何迹象,甚至没有发生任何事情。我在 shell 中尝试了 xmonad --restart 命令并将 xmonad 中的 mod-q 绑定到 spawnPipe "xmonad --restart"io sendRestart - 似乎都不起作用。当我关闭我的 Xserver 并手动重新启动它时,会显示所有更新,但现在热交换更改似乎不起作用。是否需要同时查看两个单独的二进制文件 - 当前的和新的?

编辑:我一直在通过阅读xmonadxmonad-entryhelperX11 的源代码来解决这个问题。我目前正在挑选这个:

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

我还不熟悉 X11 API,但让我感到奇怪的是 internAtom 函数以及 XMONAD_RESTART 在客户端消息中的用途。还有这个处理程序:

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

所以我猜原子只是用于标识消息事件的临时字符串? 当我运行重新启动时,我没有收到任何错误消息,所以它看起来好像一直到操作句柄:

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)

我怀疑这里有一个权限问题,xmonad-x86_64-linux 在由 xmonad 的系统安装而不是我的沙盒系统(目前符号链接到堆栈生成的二进制文件)编译和启动它时,有一个权限问题。

【问题讨论】:

    标签: haskell xmonad


    【解决方案1】:

    事实证明,问题是我无法使用堆栈生成的 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 并从现在开始调用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2020-03-23
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多