Clickable workspaces

1.5k views Asked by At

I'm using XMonad in combination with two xmobar instances, and I'm using IndependentScreens because I have a dual monitor setup. I'm having an issue with clickable workspaces ever since I introduced the second monitor. The thing is, IndependentScreens labels workspaces as 0_1, 1_1, 0_2, 1_2, ..., and the code I had worked only based on WorkspaceId, not ScreenId. I've compiled xmonad and xmonad-contrib from source so that I can use XMonad.Util.ClickableWorkspaces, however, the documentation is obscure and I couldn't find an example of proper usage anywhere. I've tried various things not worth mentioning, IMO.

This is my config:

import System.IO
import XMonad
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ServerMode
import XMonad.Hooks.SetWMName
import XMonad.Layout.IndependentScreens
import XMonad.Layout.Gaps
import XMonad.Layout.Spacing
import XMonad.Util.EZConfig (additionalKeysP)
import XMonad.Util.Run (spawnPipe)
import Data.Ord
import qualified XMonad.StackSet as W
import qualified Data.Map as M
import XMonad.Util.WorkspaceCompare
import XMonad.Util.ClickableWorkspaces

myLayout = gaps [(U, 10), (R, 10), (L, 10), (D, 10)] $ spacingRaw True (Border 0 10 10 10) True (Border 10 10 10 10) True $
             layoutHook def

myWorkspaces = 
  [ (xK_1, "1")
  , (xK_2, "2")
  , (xK_3, "3")
  , (xK_4, "4")
  , (xK_5, "5")
  , (xK_6, "6")
  , (xK_7, "7")
  , (xK_8, "8")
  , (xK_9, "9")
  , (xK_0, "10")
  , (xK_minus, "11")
  , (xK_equal, "12")
  ]


myKeys conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $
    [ ((modMask, key), windows $ onCurrentScreen W.greedyView ws)
      | (key, ws) <- myWorkspaces
    ]
    ++
    [ ((modMask .|. shiftMask, key), windows $ onCurrentScreen W.shift ws)
      | (key, ws) <- myWorkspaces
    ]
    ++
    [
    -- Spawn the terminal
      ((modMask .|. shiftMask, xK_Return), spawn $ XMonad.terminal conf)
    
    -- Spawn dmenu
    , ((modMask, xK_p), spawn "dmenu_run")

    -- Close focused window 
    , ((modMask .|. shiftMask, xK_c), kill)
 
     -- Rotate through the available layout algorithms
    , ((modMask, xK_space ), sendMessage NextLayout)
 
    --  Reset the layouts on the current workspace to default
    , ((modMask .|. shiftMask, xK_space), setLayout $ XMonad.layoutHook conf)
 
    -- Resize viewed windows to the correct size
    , ((modMask, xK_n), refresh)
 
    -- Move focus to the next window
    , ((modMask, xK_Tab), windows W.focusDown)
 
    -- Move focus to the next window
    , ((modMask, xK_j), windows W.focusDown)
 
    -- Move focus to the previous window
    , ((modMask, xK_k), windows W.focusUp)
 
    -- Move focus to the master window
    , ((modMask, xK_m), windows W.focusMaster)
 
    -- Swap the focused window and the master window
    , ((modMask, xK_Return), windows W.swapMaster)
 
    -- Swap the focused window with the next window
    , ((modMask .|. shiftMask, xK_j), windows W.swapDown)
 
    -- Swap the focused window with the previous window
    , ((modMask .|. shiftMask, xK_k), windows W.swapUp)
 
    -- Shrink the master area
    , ((modMask, xK_h), sendMessage Shrink)
 
    -- Expand the master area
    , ((modMask, xK_l), sendMessage Expand)
 
    -- Push window back into tiling
    , ((modMask, xK_t), withFocused $ windows . W.sink)
 
    -- Increment the number of windows in the master area
    , ((modMask, xK_comma), sendMessage (IncMasterN 1))
 
    -- Deincrement the number of windows in the master area
    , ((modMask, xK_period), sendMessage (IncMasterN (-1)))
 
    -- toggle the status bar gap
    , ((modMask, xK_b), sendMessage ToggleStruts)
 
    -- Restart xmonad
    , ((modMask,  xK_q), broadcastMessage ReleaseResources >> restart "xmonad" True)
    ]

myAdditionalKeysP =
    [
      ("M-<F2>", spawn "thunar")
    , ("M-<F3>", spawn "firefox")
    , ("M-<F4>", spawn "code")
    , ("M-<F5>", spawn "thunderbird")
    , ("M-<Escape>", spawn "xfce4-appfinder")
    , ("M4-<Print>", spawn "xfce4-screenshooter")
    , ("M4-<KP_Add>", spawn "amixer -D pulse sset Master 5%+")
    , ("M4-<KP_Subtract>", spawn "amixer -D pulse sset Master 5%-")
    , ("M-C-p", spawn "passmenu") 
    , ("M-C-c", spawn "clipmenu")
    , ("M-C-m", spawn "mailwatch_restart")
    , ("M-C-x", spawn "xfce4-panel -r")
    , ("M-C-<Left>", spawn "playerctl previous")
    , ("M-C-<Right>", spawn "playerctl next")
    , ("M-C-<Space>", spawn "playerctl play-pause")
    ]

clickable' :: WorkspaceId -> String
clickable' w = xmobarAction ("xmonadctl view\\\"" ++ w ++ "\\\"") "1" w

compareNumbers = comparing (read :: String -> Int)

pp h s = marshallPP s def 
    { ppOutput = hPutStrLn h
    , ppCurrent = xmobarColor "blue" "" . wrap "[" "]"
    , ppHiddenNoWindows = xmobarColor "grey" "" . clickable'
    , ppVisible = wrap "(" ")"
    , ppUrgent  = xmobarColor "red" "yellow"
    , ppOrder = \(ws:_:_:_) -> [pad ws]
    , ppHidden = clickable'
    , ppSort = mkWsSort $ return compareNumbers
    }

main = do
    xmprocs <- mapM (\i -> spawnPipe $ "xmobar ~/.config/xmobar/xmobarrc-" ++ show i ++ " -x" ++ show i) [0..1]
    xmonad $ docks def
        {
          workspaces = withScreens 2 (map show [1..12])
          , keys = myKeys
          , borderWidth = 2
          , focusedBorderColor = "#226fa5"
          , normalBorderColor = "#191919"
          , handleEventHook = serverModeEventHookCmd
                            <+> serverModeEventHook
                            <+> serverModeEventHookF "XMONAD_PRINT" (io . putStrLn)
          , layoutHook = avoidStruts myLayout
          , logHook = mapM_ dynamicLogWithPP $ zipWith pp xmprocs [0..1]
          , startupHook = setWMName "LG3D"
          , manageHook = manageDocks
        } `additionalKeysP` myAdditionalKeysP

How can I properly use clickablePP with my setup, or whatever is needed to make the workspaces clickable?

2

There are 2 answers

0
Daniel Wagner On

Something like this should work, I think:

clickable' :: ScreenId -> VirtualWorkspace -> String
clickable' s w = xmobarAction ("xmonadctl view\\\"" ++ marshall s w ++ "\\\"") "1" w

pp h s = marshallPP s def
    { ppHiddenNoWindows = xmobarColor "grey" "" . clickable' s
    , -- and the other stuff
    }

I haven't tested it, though...

0
Joaquin Flores On

This guy has this in his xmonad.hs

myClickableWorkspaces :: [String]
myClickableWorkspaces = clickable . (map xmobarEscape)
           -- $ [" 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 "]
           $ [" dev ", " www ", " sys ", " doc ", " vbox ", " chat ", " mus ", " vid ", " gfx "]
    where
        clickable l = [ "<action=xdotool key super+" ++ show (n) ++ ">" ++ ws ++ "</action>" |
                  (i,ws) <- zip [1..9] l,
                  let n = i ]

and in his xmobarrc

, commands = [
              ...
             -- The workspaces are 'clickable' in my configs.
             , Run UnsafeStdinReader
             ]
, template = " <action=`xdotool key control+alt+g`>...

and it looks that works, at least for him. You'll need 'xdotool' to make this work, in arch you can find it in the community repo, or clone it from here.