You are not logged in.

#1 2018-02-10 20:29:47

cameo
Member
Registered: 2012-08-18
Posts: 119

xmonad.hs: logHook vs. workspaces ..sigh~

Hi all Xmonad or Haskell veterans!

Well, my intention is to re-write a former overly configured xmonad.hs from scratch – and to finally have clickable workspaces in dzen along with "manageHook/doShift"-stuff then as well! (Note that I want to have the workspaces displayed separately.)

However this task not just still refuses to work – it's even worse! One of the symptoms is that the workspace dzen-bar shows up like this:

1234567890<action=xdotool key super+1>0</action>

though it's neither (left) clickable or has got a tenth workspace "0", i.e. just the default nine. Further, any workspace assignments are ignored.

Besides, the dzen-bar is not recognized as a dock (while with X.H.Config.Xfce, xfce4-panel is); it's XMonad via cabal-install along with Xfce4 by the way.

The trouble remains the same with or without Xfce involved, say if you have Xfce4 installed, configured, "XMonad.Config.Desktop" loaded, and replace "def" with "xfceConfig" it doesn't make a difference: the problem appears in a standard XMonad config as well. So there must be something wrong with the pretty printer(s) or the "logHook" or the "manageHook" – probably something stupid, like a missing "dzenEscape" or a typo, despite "xmonad --recompile"s well. Removing "xmonad.{state,error,o,hi}" doesn't help it. And I just can't figure it out since a couple of days, nearly biting my desk~

So I want first to have "myWorkspaces" recognized, and then enable their clickability (that for "myDzenStatus" runs nicely).

This is my recent xmonad.hs, ready for testing with or without Xfce (currently I don't care about aesthetics or overlaps here, for now I just want to have the basics run!):

import XMonad
import XMonad.Config.Desktop
--import XMonad.Config.Xfce
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.ManageDocks
import XMonad.Util.EZConfig (additionalKeysP)
import XMonad.Util.Run (spawnPipe)
--import Data.List    -- supplying a ws list for clickable workspaces (elemIndex)
import System.IO (hPutStrLn)

main :: IO ()
main = do
  status  <- spawnPipe myDzenStatus
  wsBar  <- spawnPipe myWsBar
  xmonad $ def -- xfceConfig 
     { modMask    = mod4Mask
     , terminal   = myTerminal
     , manageHook = manageDocks <+> manageHook def   -- manageHook xfceConfig
     , logHook    = logHook def                  -- logHook xfceConfig -- <+> ewmhDesktopsLogHook
                    <+> myLogHookA status
                    <+> myLogHookB wsBar
     , layoutHook = avoidStruts $ layoutHook def
     } `additionalKeysP` myKeys

myTerminal = "urxvtc -e fish"

myDzenStyle = " -fg '#DCDCCC' -bg '#111111'"
myDzenFont  = " -fn 'Arial-12'"
myTitleFont = " -fn 'Arial-14:autohint=true'"
myEmptyTitleFont = " -fn 'Arial-14:italic'"
myWsFont    = " -fn 'Arial-20'" --" -fn 'MarVAlea-23'"

colorBlack    = "#111111"
colorWhite    = "#DCDCCC"
colorOrange   = "#DFAF8F"
colorMagenta  = "#dc8cc3"
colorBlue     = "#8cd0d3"
colorGrayAlt  = "#7F7F7F"

myDzenStatus = "dzen2 -x '60' -w '900' -ta 'l' -h '48'" ++ myDzenStyle
myWsBar = "dzen2 -x '108' -w '824' -ta 'l' -h '24'" ++ myDzenStyle ++ myWsFont

myLogHookA h = dynamicLogWithPP	$ myStatusPP { ppOutput = hPutStrLn h }
myLogHookB h = dynamicLogWithPP $ myWsPP { ppOutput = hPutStrLn h }


myStatusPP   = dzenPP -- pretty printer for tiling layout and current window title
      { ppOrder  = \(ws:l:t:_) -> [l,t]
      , ppExtras = []
      , ppSep    = ""
      , ppLayout = dzenColor colorYellow colorBlack . wrapClickLayout . dzenEscape
      , ppTitle  = dzenColor colorOrange colorBlack
                 . wrapClickTitle .
                 (\x ->	if null x
                        then "^fn(" ++ myEmptyTitleFont ++ ")" ++ "  xxxxx"
                        else "^fn(" ++ myTitleFont ++ ")" ++ "  " ++ shorten 90 x ++ "  "
                 ) . dzenEscape
      }
        where
        wrapClickLayout content = "^ca(1,xdotool key super+space)" ++ content ++ "^ca()"
        wrapClickTitle content  = "^ca(1,xdotool key super+j)" ++ content ++ "^ca()"

myWsPP       = dzenPP
      { ppOrder  = \(ws:l:t:_) -> [ws]
--      , ppSort   = ppSort def
      , ppCurrent = dzenColor colorBlue colorBlack      -- . wrapClickWs
      , ppUrgent = dzenColor colorMagenta colorBlack    -- . wrapClickWs
      , ppVisible = dzenColor colorOrange colorBlack    -- . wrapClickWs
      , ppHidden = dzenColor colorWhite colorBlack      -- . wrapClickWs
      , ppHiddenNoWindows = dzenColor colorGrayAlt colorBlack -- . wrapClickWs
      , ppWsSep  = ""
      , ppSep    = ""
      }
{-     where
        wrapClickWs content = "^ca(l,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()" |
                           (i,ws) <- zip ([1..9] ++ [0]) content, 
                           let n = if i == 10 then 0 else i -- needed for 10 workspaces
   ... something like that (but without errors) ...
-}
-- letters for testing; will become literals [1..9] ++ [0] 
--myWorkspaces   :: [String]
myWorkspaces   = ["a","b","c","d","e","f","g","h","i","k"] -- without effect!..

{- Clickable workspaces w/ dzen, configurable in at least two ways, either 

(1) in
myWorkspaces = clickable $ map show $ [1..9] ++ [0]	--	 $ map show $ [1..9] ++ [0]		clickable . (map dzenEscape) 
        where
          clickable l     = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" |
                            (i,ws) <- zip [1..] l,
                            let n = if i == 10 then 0 else i ] -- needed for 10 workspaces
     ... without effect ...

OR (2) in myWsPP (see above)
-}

myKeys = [ ("M-S-c" , kill) 
     , ("<Print>" , spawn "scrot")
     , ("M-q" , do
                spawn "killall -9 compton dzen2 conky"
                restart "xmonad" True)
     , ("M-C-c" , kill)
     , ("M-<Return>", spawn myTerminal)
--- Sound control
     , ("<XF86AudioMute>", spawn "amixer -q -D pulse sset Master toggle")
     , ("<XF86AudioRaiseVolume>", spawn "amixer -q -D pulse sset Master 2000+ unmute")
     , ("<XF86AudioLowerVolume>", spawn "amixer -q -D pulse sset Master 2000- unmute")
     , ("M-<XF86AudioRaiseVolume>", spawn "urxvtc -e alsamixer")
     , ("M-<XF86AudioLowerVolume>", spawn "urxvtc -e alsamixer")
     , ("<XF86AudioNext>", spawn "ncmpcpp next")
     , ("<XF86AudioPrev>", spawn "ncmpcpp prev")
     , ("<XF86AudioPlay>", spawn "ncmpcpp toggle")
     , ("<XF86AudioStop>", spawn "ncmpcpp stop")
     , ("M-S-f", spawn "firefox")
     ]

Last edited by cameo (2018-02-11 10:09:54)

Offline

#2 2018-02-11 16:24:14

cameo
Member
Registered: 2012-08-18
Posts: 119

Re: xmonad.hs: logHook vs. workspaces ..sigh~

Now fiddling around just with numbered workspaces and only a single status bar:

myWorkspaces   = [1..10]

myDzenStatus = "dzen2 -x '60' -w '900' -ta 'l' -h '48'" ++ myDzenStyle

myLogHookA status = dynamicLogWithPP $ myStatusPP { ppOutput = hPutStrLn status }

-- with "myWsPP       = ... " and other lines commented out in "main" and "logHook"

while this snippet of code

myStatusPP   = dzenPP -- pretty printer for tiling layout and current window title
      { ppOrder  = def 
      , ppExtras = []
      , ppSep    = ""
      , ppLayout = dzenColor colorYellow colorBlack . wrapClickLayout . dzenEscape
      , ppTitle  = dzenColor colorOrange colorBlack
                 . wrapClickTitle .
                 (\x ->	if null x
                        then "^fn(" ++ myEmptyTitleFont ++ ")" ++ "  xxxxx"
                        else "^fn(" ++ myTitleFont ++ ")" ++ "  " ++ shorten 90 x ++ "  "	-- cut text string after 90 characters
                 ) . dzenEscape    -- . ("^p(134;-3) " ++)
-- from former myWsPP
      , ppCurrent = dzenColor colorBlue colorBlack-- . wrapClickWs -- error! --   . dzenEscape -- no effect!
      , ppUrgent = dzenColor colorMagenta colorBlack-- . wrapClickWs -- error! -- . dzenEscape no effect!
      , ppVisible = dzenColor colorOrange colorBlack-- . wrapClickWs -- error! -- . dzenEscape -- no effect!
      , ppHidden = dzenColor colorWhite colorBlack-- . wrapClickWs -- error! -- . dzenEscape --  o effect!
      , ppHiddenNoWindows = dzenColor colorGrayAlt colorBlack -- . wrapClickWs . dzenEscape -- no effect!
      , ppWsSep  = ""
      }
        where
        wrapClickLayout content = "^ca(1,xdotool key super+space)" ++ content ++ "^ca()"
        wrapClickTitle content  = "^ca(1,xdotool key super+j)" ++ content ++ "^ca()"
-- former myWsPP
        wrapClickWs l = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" | (i,ws) <- zip [1..] l,
                             let n = if i == 10 then 0 else i ] -- needed for 10 workspaces

gives me errors like

xmonad.hs:131:21: error:
    • Couldn't match type ‘[Char]’ with ‘WorkspaceId -> String’
      Expected type: WorkspaceId -> String
        Actual type: String
    • In the ‘ppCurrent’ field of a record
      In the expression:
        dzenPP
          {ppOrder = def, ppExtras = [], ppSep = "",
           ppLayout = dzenColor colorYellow colorBlack
                        . wrapClickLayout . dzenEscape,
           ppTitle = dzenColor colorOrange colorBlack
                       . wrapClickTitle
                           . (\ x
                                -> if null x then
                                       "^fn(" ++ myEmptyTitleFont ++ ")" ++ "  xxxxx"
                                   else
                                       "^fn(" ++ myTitleFont ++ ")" ++ "  " ++ shorten 90 x ++ "  ")
                               . dzenEscape,
           ppCurrent = dzenColor colorBlue colorBlack $ wrapClickWs,
           ppUrgent = dzenColor colorMagenta colorBlack $ wrapClickWs,
           ppVisible = dzenColor colorOrange colorBlack $ wrapClickWs,
           ppHidden = dzenColor colorWhite colorBlack $ wrapClickWs,
           ppHiddenNoWindows = dzenColor colorGrayAlt colorBlack
                                 $ wrapClickWs,
           ppWsSep = ""}
      In an equation for ‘myStatusPP’:
          myStatusPP
            = dzenPP
                {ppOrder = def, ppExtras = [], ppSep = "",
                 ppLayout = dzenColor colorYellow colorBlack
                              . wrapClickLayout . dzenEscape,
                 ppTitle = dzenColor colorOrange colorBlack
                             . wrapClickTitle
                                 . (\ x
                                      -> if null x then
                                             "^fn(" ++ myEmptyTitleFont ++ ")" ++ "  xxxxx"
                                         else
                                             "^fn("
                                               ++
                                                 myTitleFont ++ ")" ++ "  " ++ shorten 90 x ++ "  ")
                                     . dzenEscape,
                 ppCurrent = dzenColor colorBlue colorBlack $ wrapClickWs,
                 ppUrgent = dzenColor colorMagenta colorBlack $ wrapClickWs,
                 ppVisible = dzenColor colorOrange colorBlack $ wrapClickWs,
                 ppHidden = dzenColor colorWhite colorBlack $ wrapClickWs,
                 ppHiddenNoWindows = dzenColor colorGrayAlt colorBlack
                                       $ wrapClickWs,
                 ppWsSep = ""}
            where
                wrapClickLayout content
                  = "^ca(1,xdotool key super+space)" ++ content ++ "^ca()"
                wrapClickTitle content
                  = "^ca(1,xdotool key super+j)" ++ content ++ "^ca()"
                wrapClickWs l
                  = ["^ca(1,xdotool key super+"
                       ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" |
                       (i, ws) <- zip [1 .. ] l, let ...]
    |
131 |       , ppCurrent = dzenColor colorBlue colorBlack $ wrapClickWs -- error! --   . dzenEscape -- no effect!
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

xmonad.hs:131:54: error:
    • Couldn't match type ‘[[Char]] -> [[Char]]’ with ‘[Char]’
      Expected type: String
        Actual type: [[Char]] -> [[Char]]
    • Probable cause: ‘wrapClickWs’ is applied to too few arguments
      In the second argument of ‘($)’, namely ‘wrapClickWs’
      In the ‘ppCurrent’ field of a record
      In the expression:
        dzenPP
          {ppOrder = def, ppExtras = [], ppSep = "",
           ppLayout = dzenColor colorYellow colorBlack
                        . wrapClickLayout . dzenEscape,
           ppTitle = dzenColor colorOrange colorBlack
                       . wrapClickTitle
                           . (\ x
                                -> if null x then
                                       "^fn(" ++ myEmptyTitleFont ++ ")" ++ "  xxxxx"
                                   else
                                       "^fn(" ++ myTitleFont ++ ")" ++ "  " ++ shorten 90 x ++ "  ")
                               . dzenEscape,
           ppCurrent = dzenColor colorBlue colorBlack $ wrapClickWs,
           ppUrgent = dzenColor colorMagenta colorBlack $ wrapClickWs,
           ppVisible = dzenColor colorOrange colorBlack $ wrapClickWs,
           ppHidden = dzenColor colorWhite colorBlack $ wrapClickWs,
           ppHiddenNoWindows = dzenColor colorGrayAlt colorBlack
                                 $ wrapClickWs,
           ppWsSep = ""}
    |
131 |       , ppCurrent = dzenColor colorBlue colorBlack $ wrapClickWs -- error! --   . dzenEscape -- no effect!
    |                                                      ^^^^^^^^^^^

...

Sounds logic according to the the official doc, saying

ppCurrent :: WorkspaceId -> String	how to print the tag of the currently focused workspace
ppVisible :: WorkspaceId -> String		how to print tags of visible but not focused workspaces (xinerama only)
ppHidden :: WorkspaceId -> String		how to print tags of hidden workspaces which contain windows
ppHiddenNoWindows :: WorkspaceId -> String	how to print tags of empty hidden workspaces
ppUrgent :: WorkspaceId -> String		format to be applied to tags of urgent workspaces.
...

So it's in here:

        wrapClickWs l = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" | (i,ws) <- zip [1..] l,
                             let n = if i == 10 then 0 else i ] -- needed for 10 workspaces

But how to change the "WorkspaceId"s to strings properly?

However, announcing

        wrapClickWs :: WorkspaceId -> String
        wrapClickWs l = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" | (i,ws) <- zip [1..] l,
                             let n = if i == 10 then 0 else i ] -- needed for 10 workspaces

(according to the doc's subsection "Constructors") leads to the following

xmonad.hs:143:27: error:
    • Couldn't match expected type ‘Char’ with actual type ‘[Char]’
    • In the expression:
        "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()"
      In the expression:
        ["^ca(1,xdotool key super+"
           ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" |
           (i, ws) <- zip [1 .. ] l, let n = if i == 10 then 0 else i]
      In an equation for ‘wrapClickWs’:
          wrapClickWs l
            = ["^ca(1,xdotool key super+"
                 ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" |
                 (i, ws) <- zip [1 .. ] l, let n = ...]
    |
143 |         wrapClickWs l = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" | (i,ws) <- zip [1..] l,
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

xmonad.hs:143:76: error:
    • Couldn't match expected type ‘[Char]’ with actual type ‘Char’
    • In the first argument of ‘(++)’, namely ‘ws’
      In the second argument of ‘(++)’, namely ‘ws ++ "^ca()^ca()"’
      In the second argument of ‘(++)’, namely
        ‘")" ++ ws ++ "^ca()^ca()"’
    |
143 |         wrapClickWs l = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()^ca()" | (i,ws) <- zip [1..] l,
    |                                                                            ^^

So maybe there's some progress – but what am I supposed to do here exactly?

Offline

#3 2018-02-11 21:13:31

cameo
Member
Registered: 2012-08-18
Posts: 119

Re: xmonad.hs: logHook vs. workspaces ..sigh~

At the least, with some lines copied from here I made the stuff compiling smoothly – but now the output is an empty status bar!

...
import Data.List -- preparing a ws list (elemIndex)
...

myWorkspaces = map show $ [1..9] ++ [0]

myStatusPP   = dzenPP
      { ppOrder  = def 
      , ppExtras = []
      , ppSep    = ""
      , ppLayout = dzenColor colorYellow colorBlack . wrapClickLayout . dzenEscape
      , ppTitle  = dzenColor colorOrange colorBlack
                 . wrapClickTitle .
                 (\x -> if null x
                        then "^fn(" ++ myEmptyTitleFont ++ ")" ++ "  xxxxx"
                        else "^fn(" ++ myTitleFont ++ ")" ++ "  " ++ shorten 90 x ++ "  "
                 ) . dzenEscape    -- . ("^p(134;-3) " ++)
      , ppCurrent = dzenColor colorBlue colorBlack . wrapClickWs . (\a -> (a,a))-- . dzenEscape -- no effect!
      , ppUrgent = dzenColor colorMagenta colorBlack . wrapClickWs . (\a -> (a,a))-- . dzenEscape -- no effect!
      , ppVisible = dzenColor colorOrange colorBlack . wrapClickWs . (\a -> (a,a))-- . dzenEscape -- no effect!
      , ppHidden = dzenColor colorWhite colorBlack . wrapClickWs . (\a -> (a,a))-- . dzenEscape -- no effect!
      , ppHiddenNoWindows = dzenColor colorGrayAlt colorBlack . wrapClickWs . (\a -> (a,a))-- . dzenEscape  AND/OR . dzenStrip -- no effect!
      , ppWsSep  = ""
      }
        where
        wrapClickLayout content = "^ca(1,xdotool key super+space)" ++ content ++ "^ca()"
        wrapClickTitle content  = "^ca(1,xdotool key super+j)" ++ content ++ "^ca()"
        currentWsIndex w = case (elemIndex w myWorkspaces) of
          Nothing -> "1"
          Just n -> show (n+1)
        wrapClickWs (idx,str) = "^ca(1," ++ xdo "w;" ++ xdo index ++ ")" ++ "^ca(3," ++ xdo "e;" ++ xdo index ++ ")" ++ str ++ "^ca()"
          where
            index = currentWsIndex idx
            xdo key   = "xdotool key super+" ++ key

...

What the heck?!

Boy, this is annoying like stirring in a pot with cold coffee with the finger, but you can't tip it away because you fear to miss the golden spoon that's lost in it~

Offline

Board footer

Powered by FluxBB