Sravan Balaji 1bb3509736 DWM Keybindings & Autostart
- Replace commented out code with no tangle blocks
- Port dwm keybindings and autostart to xmonad
- Add more comments
2021-05-09 18:45:13 -04:00
2021-05-08 10:42:16 -04:00
2021-05-09 18:45:13 -04:00
2021-05-09 18:45:13 -04:00

Personal Xmonad Configuration with Xmobar

Welcome

My personal configuration of Xmonad, written as an Org Mode document.

Run the block below with C-c C-c to tangle code blocks to config file.

  (org-mode-restart)
  (org-babel-tangle)

Imports

  import XMonad hiding ( (|||) )
  import XMonad.Layout.LayoutCombinators (JumpToLayout(..), (|||))
  import XMonad.Config.Desktop
  import Data.Monoid
  import System.Exit
  import qualified XMonad.StackSet as W
  import qualified Data.Map        as M

  -- system
  import System.IO (hPutStrLn)

  -- util
  import XMonad.Util.Run (safeSpawn, unsafeSpawn, runInTerm, spawnPipe)
  import XMonad.Util.SpawnOnce
  import XMonad.Util.EZConfig (additionalKeysP, additionalMouseBindings)

  -- hooks
  import XMonad.Hooks.DynamicLog
  import XMonad.Hooks.ManageDocks (avoidStruts, docksStartupHook, manageDocks, ToggleStruts(..))
  import XMonad.Hooks.EwmhDesktops
  import XMonad.Hooks.ManageHelpers (isFullscreen, isDialog, doFullFloat, doCenterFloat, doRectFloat)
  import XMonad.Hooks.Place (placeHook, withGaps, smart)

  -- actions
  import XMonad.Actions.CopyWindow

  -- layout
  import XMonad.Layout.NoBorders 
  import XMonad.Layout.Spacing (spacing)
  import XMonad.Layout.GridVariants (Grid(Grid))
  import XMonad.Layout.ResizableTile

Terminal

The preferred terminal program, which is used in a binding below and by certain contrib modules.

  myTerminal      = "kitty"

Window Behavior & Appearance

Mouse Focus

Whether focus follows the mouse pointer.

  myFocusFollowsMouse :: Bool
  myFocusFollowsMouse = True

Whether clicking on a window to focus also passes the click to the window

  myClickJustFocuses :: Bool
  myClickJustFocuses = False

Window Border Size

Width of the window border in pixels.

  myBorderWidth   = 2

Window Border Colors

Border colors for unfocused and focused windows, respectively.

  myNormalBorderColor  = "#4D4D4D"
  myFocusedBorderColor = "#BD93F9"

Workspaces

The default number of workspaces (virtual screens) and their names. By default we use numeric strings, but any string may be used as a workspace name. The number of workspaces is determined by the length of this list.

A tagging example:

  workspaces = ["web", "irc", "code" ] ++ map show [4..9]

Workspace Names w/ Icons:

  myWorkspaces    = ["\xf868\x2081", "\xfd2c\x2082", "\xf2ce\x2083", "\xf1bc\x2084", "\xfa9e\x2085", "\xe795\x2086", "\xf667\x2087", "\xf11b\x2088", "\xf085\x2089"]
  myWorkspaces    = ["1:\xf868", "2:\xfd2c", "3:\xf2ce", "4:\xf1bc", "5:\xfa9e", "6:\xe795", "7:\xf667", "8:\xf11b", "9:\xf085"]

Actual Workspace Definition:

  myWorkspaces    = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

Keybindings

Modifier Key

modMask lets you specify which modkey you want to use. The default is mod1Mask ("left alt"). You may also consider using mod3Mask ("right alt"), which does not conflict with emacs keybindings. The "windows key" is usually mod4Mask.

  myModMask       = mod4Mask

Default Keybindings

These default keybindings are left for reference, but are not actually used in my config. desktopConfig automatically uses the default keybindings shown below. I am overwriting some of these in the *EZConfig Keybindings

NOT IN USE

  myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $
      -- launch a terminal
      [ ((modm .|. shiftMask, xK_Return), spawn $ XMonad.terminal conf)

      -- launch rofi drun
      , ((modm,               xK_p     ), spawn "rofi -show drun")

      -- close focused window
      , ((modm .|. shiftMask, xK_c     ), kill)

       -- Rotate through the available layout algorithms
      , ((modm,               xK_space ), sendMessage NextLayout)

      --  Reset the layouts on the current workspace to default
      , ((modm .|. shiftMask, xK_space ), setLayout $ XMonad.layoutHook conf)

      -- Resize viewed windows to the correct size
      , ((modm,               xK_n     ), refresh)

      -- Move focus to the next window
      , ((modm,               xK_Tab   ), windows W.focusDown)

      -- Move focus to the next window
      , ((modm,               xK_j     ), windows W.focusDown)

      -- Move focus to the previous window
      , ((modm,               xK_k     ), windows W.focusUp  )

      -- Move focus to the master window
      , ((modm,               xK_m     ), windows W.focusMaster  )

      -- Swap the focused window and the master window
      , ((modm,               xK_Return), windows W.swapMaster)

      -- Swap the focused window with the next window
      , ((modm .|. shiftMask, xK_j     ), windows W.swapDown  )

      -- Swap the focused window with the previous window
      , ((modm .|. shiftMask, xK_k     ), windows W.swapUp    )

      -- Shrink the master area
      , ((modm,               xK_h     ), sendMessage Shrink)

      -- Expand the master area
      , ((modm,               xK_l     ), sendMessage Expand)

      -- Push window back into tiling
      , ((modm,               xK_t     ), withFocused $ windows . W.sink)

      -- Increment the number of windows in the master area
      , ((modm,               xK_i ), sendMessage (IncMasterN 1))

      -- Deincrement the number of windows in the master area
      , ((modm,               xK_d), sendMessage (IncMasterN (-1)))

      -- Quit xmonad
      , ((modm .|. shiftMask, xK_q     ), io (exitWith ExitSuccess))

      -- Restart xmonad
      , ((modm              , xK_q     ), spawn "xmonad --recompile; xmonad --restart")

      -- Run xmessage with a summary of the default keybindings (useful for beginners)
      , ((modm .|. shiftMask, xK_slash ), spawn ("echo \"" ++ help ++ "\" | xmessage -file -"))
      ]
      ++

      -- mod-[1..9], Switch to workspace N
      -- mod-shift-[1..9], Move client to workspace N
      [((m .|. modm, k), windows $ f i)
          | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9]
          , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]
      ++

      -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3
      -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3
      [((m .|. modm, key), screenWorkspace sc >>= flip whenJust (windows . f))
          | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]
          , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]

EZConfig Keybindings

  myKeys =
    [
    -- dwm-like add window to a specific workspace
      ("M-" ++ m ++ k, windows $ f i)
        | (i, k) <- zip (myWorkspaces) (map show [1 :: Int ..])
        , (f, m) <- [(W.view, ""), (W.shift, "S-"), (copy, "S-C-")]
    ]
    ++
    [
    -- dwm-like add/remove window to/from all workspaces
      ("S-C-a", windows copyToAll)  -- copy window to all workspaces
    , ("S-C-z", killAllOtherCopies) -- kill copies of window on other workspaces

    -- modify tiled window size
    , ("M-a", sendMessage MirrorShrink) -- decrease vertical window size
    , ("M-z", sendMessage MirrorExpand) -- increase vertical window size

    -- toggle struts for xmobar
    , ("M-s", sendMessage ToggleStruts)

    -- switch directly to a layout
    , ("M-f", sendMessage $ JumpToLayout "Full")
    , ("M-t", sendMessage $ JumpToLayout "Spacing ResizableTall")
    , ("M-g", sendMessage $ JumpToLayout "Spacing Grid")

    -- launch rofi
    , ("M-p", spawn "rofi -show combi")
    , ("M-c", spawn "rofi -show clipboard")

    -- volume control
    , ("<XF86AudioRaiseVolume>", spawn "pactl set-sink-volume @DEFAULT_SINK@ +1%")  -- increase volume
    , ("<XF86AudioLowerVolume>", spawn "pactl set-sink-volume @DEFAULT_SINK@ -1%")  -- decrease volume
    , ("<XF86AudioMute>",        spawn "pactl set-sink-mute @DEFAULT_SINK@ toggle") -- mute volume

    -- media control
    , ("<XF86AudioPlay>",     spawn "playerctl --player=playerctld play-pause") -- play / pause
    , ("C-<XF86AudioPlay>",   spawn "playerctl --player=playerctld next")       -- next
    , ("C-S-<XF86AudioPlay>", spawn "playerctl --player=playerctld previous")   -- previous
    , ("S-<XF86AudioPlay>",   spawn "playerctld shift")                         -- change player

    -- notification control
    , ("M-n",     spawn "dunstctl context")           -- notification context menu
    , ("M-C-n",   spawn "dunstctl close")             -- close notification
    , ("M-S-n",   spawn "dunstctl history-pop")       -- pop history
    , ("M-C-S-n", spawn "dunstctl set-paused toggle") -- toggle do not disturb

    -- system control
    , ("M-q",     spawn "xmonad --recompile; xmonad --restart") -- recompile and restart xmonad
    , ("M-C-S-q", io (exitWith ExitSuccess))                    -- quit xmonad
    , ("M-C-S-l", spawn "light-locker-command --lock")          -- lock
    , ("M-C-S-s", spawn "systemctl suspend")                    -- suspend

    -- toggle compositor
    , ("M-<Esc>", spawn "/home/sravan/.config/picom/toggle_picom.sh")

    -- screenshot
    , ("<Print>", spawn "flameshot gui")
    ]

Mouse Bindings

Mouse bindings: default actions bound to mouse events

  myMouseBindings (XConfig {XMonad.modMask = modm}) = M.fromList $

      -- mod-button1, Set the window to floating mode and move by dragging
      [ ((modm, button1), (\w -> focus w >> mouseMoveWindow w
                                         >> windows W.shiftMaster))

      -- mod-button2, Raise the window to the top of the stack
      , ((modm, button2), (\w -> focus w >> windows W.shiftMaster))

      -- mod-button3, Set the window to floating mode and resize by dragging
      , ((modm, button3), (\w -> focus w >> mouseResizeWindow w
                                         >> windows W.shiftMaster))

      -- you may also bind events to the mouse scroll wheel (button4 and button5)
      ]

Layouts

You can specify and transform your layouts by modifying these values. If you change layout bindings be sure to use 'mod-shift-space' after restarting (with 'mod-q') to reset your layout state to the new defaults, as xmonad preserves your old layout settings by default.

The available layouts. Note that each layout is separated by |||, which denotes layout choice.

  myLayout =
    avoidStruts ( tiled ||| grid ||| monocle )
    where
       -- default tiling algorithm partitions the screen into two panes
       nmaster = 1
       delta = 3/100
       tiled_ratio = 1/2
       tiled_spacing = 10
       tiled = spacing tiled_spacing $ ResizableTall nmaster delta tiled_ratio []

       -- grid
       grid_ratio = 16/9
       grid_spacing = 10
       grid = spacing grid_spacing $ Grid grid_ratio

       -- monocle
       -- monocle = smartBorders (Full)
       monocle = noBorders (Full)

Window Rules

Execute arbitrary actions and WindowSet manipulations when managing a new window. You can use this to, for example, always float a particular program, or have a client always appear on a particular workspace.

To find the property name associated with a program, use > xprop | grep WM_CLASS and click on the client you're interested in.

To match on the WM_NAME, you can use 'title' in the same way that 'className' and 'resource' are used below.

  myManageHook = composeAll
      [ className =? "MPlayer"        --> doFloat
      , className =? "Gimp"           --> doFloat
      , resource  =? "desktop_window" --> doIgnore
      , resource  =? "kdesktop"       --> doIgnore ]

Event Handling

NOTE: EwmhDesktops users should change this to ewmhDesktopsEventHook

Defines a custom handler function for X Events. The function should return (All True) if the default handler is to be run afterwards. To combine event hooks use mappend or mconcat from Data.Monoid.

NOT IN USE

  myEventHook = mempty

Status Bars & Logging

Perform an arbitrary action on each internal state change or X event. See the XMonad.Hooks.DynamicLog extension for examples.

NOT IN USE

  myLogHook = return ()

Startup

Hook

Perform an arbitrary action each time xmonad starts or is restarted with mod-q. Used by, e.g., XMonad.Layout.PerWorkspace to initialize per-workspace layout choices.

  myStartupHook = do
    -- System Restore Processes
    spawnOnce "/home/sravan/.screenlayout/default.sh &"                     -- restore default screen layout
    spawnOnce "nitrogen --restore &"                                        -- restore wallpaper
    spawnOnce "numlockx on &"                                               -- enable numlock

    -- System Tray Applications
    spawnOnce "volctl &"                                                    -- PulseAudio Volume Control
    spawnOnce "nyrna &"                                                     -- Nyrna Application Suspend
    spawnOnce "blueman-applet &"                                            -- Blueman Bluetooth Manager
    spawnOnce "nm-applet &"                                                 -- Network Manager Applet
    spawnOnce "kdeconnect-indicator &"                                      -- KDE Connect
    spawnOnce "flameshot &"                                                 -- Flameshot Screenshot Tool
    spawnOnce "xfce4-power-manager &"                                       -- XFCE4 Power Manager

    -- Background Processes
    spawnOnce "/home/sravan/.config/picom/toggle_picom.sh &"                -- Picom Compositor
    spawnOnce "/home/sravan/.config/dunst/launch_dunst.sh &"                -- Dunst Notification Daemon
    spawnOnce "greenclip daemon &"                                          -- Greenclip Clipboard Manager
    spawnOnce "redshift -x &"                                               -- Reset redshift display gamma
    spawnOnce "redshift-gtk &"                                              -- Redshift Blue Light Filter
    spawnOnce "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &" -- GNOME Polkit Authentication Agent
    spawnOnce "light-locker --lock-on-suspend --lock-on-lid &"              -- screen lock for lightdm

Main

Now run xmonad with all the defaults we set up.

Run xmonad with the settings you specify. No need to modify this.

  main = do
    -- `xmobar -x 0` launches the bar on monitor 0
    xmproc <- spawnPipe "xmobar -x 0 /home/sravan/.xmonad/xmobar.config"
    -- launches xmobar as a dock
    xmonad $ ewmh desktopConfig
      { manageHook         = manageDocks <+> manageHook desktopConfig
      , startupHook        = myStartupHook
      , layoutHook         = myLayout
      , borderWidth        = myBorderWidth
      , terminal           = myTerminal
      , modMask            = myModMask
      , normalBorderColor  = myNormalBorderColor
      , focusedBorderColor = myFocusedBorderColor
      , logHook            = dynamicLogWithPP xmobarPP
                             { ppOutput = \x -> hPutStrLn xmproc x
                             , ppCurrent = xmobarColor "green" "" . wrap "[" "]" -- current workspace in xmobar
                             , ppVisible = xmobarColor "cyan" ""                 -- visible but not current workspace
                             , ppHidden = xmobarColor "yellow" "" . wrap "+" ""  -- hidden workspaces in xmobar
                             , ppHiddenNoWindows = xmobarColor "white" ""        -- hidden workspaces (no windows)
                             , ppTitle = xmobarColor "purple" "" . shorten 80    -- title of active window in xmobar
                             , ppSep = " | "                                     -- separators in xmobar
                             , ppUrgent = xmobarColor "red" "" . wrap "!" "!"    -- urgent workspace
                             , ppOrder = \(ws:l:t:ex) -> [ws,l,t]
                             }
          -- focusFollowsMouse  = myFocusFollowsMouse,
          -- clickJustFocuses   = myClickJustFocuses,
          -- workspaces         = myWorkspaces,
          -- keys               = myKeys,
          -- mouseBindings      = myMouseBindings,
          -- handleEventHook    = myEventHook,
      } `additionalKeysP` myKeys

Default Keybindings Reference

Finally, a copy of the default bindings in simple textual tabular format.

  help :: String
  help = unlines ["The default modifier key is 'alt'. Default keybindings:",
      "",
      "-- launching and killing programs",
      "mod-Shift-Enter  Launch xterminal",
      "mod-p            Launch dmenu",
      "mod-Shift-p      Launch gmrun",
      "mod-Shift-c      Close/kill the focused window",
      "mod-Space        Rotate through the available layout algorithms",
      "mod-Shift-Space  Reset the layouts on the current workSpace to default",
      "mod-n            Resize/refresh viewed windows to the correct size",
      "",
      "-- move focus up or down the window stack",
      "mod-Tab        Move focus to the next window",
      "mod-Shift-Tab  Move focus to the previous window",
      "mod-j          Move focus to the next window",
      "mod-k          Move focus to the previous window",
      "mod-m          Move focus to the master window",
      "",
      "-- modifying the window order",
      "mod-Return   Swap the focused window and the master window",
      "mod-Shift-j  Swap the focused window with the next window",
      "mod-Shift-k  Swap the focused window with the previous window",
      "",
      "-- resizing the master/slave ratio",
      "mod-h  Shrink the master area",
      "mod-l  Expand the master area",
      "",
      "-- floating layer support",
      "mod-t  Push window back into tiling; unfloat and re-tile it",
      "",
      "-- increase or decrease number of windows in the master area",
      "mod-comma  (mod-,)   Increment the number of windows in the master area",
      "mod-period (mod-.)   Deincrement the number of windows in the master area",
      "",
      "-- quit, or restart",
      "mod-Shift-q  Quit xmonad",
      "mod-q        Restart xmonad",
      "mod-[1..9]   Switch to workSpace N",
      "",
      "-- Workspaces & screens",
      "mod-Shift-[1..9]   Move client to workspace N",
      "mod-{w,e,r}        Switch to physical/Xinerama screens 1, 2, or 3",
      "mod-Shift-{w,e,r}  Move client to screen 1, 2, or 3",
      "",
      "-- Mouse bindings: default actions bound to mouse events",
      "mod-button1  Set the window to floating mode and move by dragging",
      "mod-button2  Raise the window to the top of the stack",
      "mod-button3  Set the window to floating mode and resize by dragging"]

Xmobar

  Config { font = "xft:FiraCode Nerd Font Mono:weight=bold:pixelsize=12:antialias=true:hinting=true"
         , additionalFonts = []
         , borderColor = "black"
         , border = TopB
         , bgColor = "black"
         , fgColor = "white"
         , alpha = 255
         , position = Top
         , textOffset = -1
         , iconOffset = -1
         , lowerOnStart = True
         , pickBroadest = False
         , persistent = False
         , hideOnStart = False
         , iconRoot = "."
         , allDesktops = True
         , overrideRedirect = True
         , commands = [ Run Weather "K7D2" ["-t","<station>: <tempF>F","-L","18","-H","25","--normal","green","--high","red","--low","lightblue"] 36000
                      , Run Network "wlp0s20f3" ["-L","0","-H","32","--normal","green","--high","red"] 10
                      , Run Cpu ["-L","3","-H","50","--normal","green","--high","red"] 10
                      , Run Memory ["-t","Mem: <usedratio>%"] 10
                      , Run Swap [] 10
                      , Run Com "uname" ["-s","-r"] "" 36000
                      , Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
                      , Run StdinReader
                      ]
         , sepChar = "%"
         , alignSep = "}{"
         , template = "%StdinReader% }\
                      \{ %cpu% | %memory% * %swap% | %wlp0s20f3% | <fc=#ee9a00>%date%</fc> | %uname%"
         }
Description
Personal build of Xmonad Window Manager
Readme 150 KiB
Languages
Haskell 80.1%
Shell 19.9%