Personal Xmonad Configuration with Polybar
- Welcome
- Imports
- Terminal
- Window Behavior & Appearance
- Workspaces
- Keybindings
- Layouts
- Window Rules
- Event Handling
- Logging
- Startup
- Status Bar
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
-- 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 (docks, avoidStruts, docksStartupHook, manageDocks, ToggleStruts(..), SetStruts(..))
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
import XMonad.Actions.CycleWS
-- layout
import XMonad.Layout.NoBorders
import XMonad.Layout.Spacing (spacingRaw, Border(Border))
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 = "alacritty"
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] workspaces = ["\xf868\x2081", "\xfd2c\x2082", "\xf2ce\x2083", "\xf1bc\x2084", "\xfa9e\x2085", "\xe795\x2086", "\xf667\x2087", "\xf11b\x2088", "\xf085\x2089"] workspaces = ["1:\xf868", "2:\xfd2c", "3:\xf2ce", "4:\xf1bc", "5:\xfa9e", "6:\xe795", "7:\xf667", "8:\xf11b", "9:\xf085"]
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 /sravan/xmonad/src/branch/master/%2AEZConfig%20Keybindings
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
("M-C-S-a", windows copyToAll) -- copy window to all workspaces
, ("M-C-S-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)
-- full mode w/ all gaps
, ("M-f", sequence_
[ sendMessage $ JumpToLayout "Full"
, sendMessage $ SetStruts [minBound .. maxBound] []])
-- full mode w/ all gaps and flatten floating windows
, ("M-S-f", sequence_
[ withFocused $ windows . W.sink
, refresh
, sendMessage $ JumpToLayout "Full"
, sendMessage $ SetStruts [minBound .. maxBound] []])
-- full mode w/ no gaps and flatten floating windows
, ("M-C-S-f", sequence_
[ withFocused $ windows . W.sink
, refresh
, sendMessage $ JumpToLayout "Full"
, sendMessage $ SetStruts [] [minBound .. maxBound]])
-- tall mode w/ all gaps
, ("M-t", sequence_
[ sendMessage $ JumpToLayout "Spacing ResizableTall"
, sendMessage $ SetStruts [minBound .. maxBound] []])
-- tall mode w/ all gaps and flatten floating windows
, ("M-S-t", sequence_
[ withFocused $ windows . W.sink
, refresh
, sendMessage $ JumpToLayout "Spacing ResizableTall"
, sendMessage $ SetStruts [minBound .. maxBound] []])
-- grid mode w/ all gaps
, ("M-g", sequence_
[ sendMessage $ JumpToLayout "Spacing Grid"
, sendMessage $ SetStruts [minBound .. maxBound] []])
-- grid mode w/ all gaps and flatten floating windows
, ("M-S-g", sequence_
[ withFocused $ windows . W.sink
, refresh
, sendMessage $ JumpToLayout "Spacing Grid"
, sendMessage $ SetStruts [minBound .. maxBound] []])
-- cycle & move between screens
, ("M-,", prevScreen)
, ("M-S-,", shiftPrevScreen)
, ("M-C-S-,", swapPrevScreen)
, ("M-.", nextScreen)
, ("M-S-.", shiftNextScreen)
, ("M-C-S-.", swapNextScreen)
-- launch rofi
, ("M-p", spawn "rofi -show combi")
, ("M-S-p", spawn "/home/sravan/.scripts/control-center.sh --rofi")
, ("M-c", spawn "rofi -show clipboard")
, ("M-b", spawn "rofi-rbw")
-- volume control
, ("<XF86AudioRaiseVolume>", spawn "/home/sravan/.scripts/pactl.sh --raise") -- increase volume
, ("<XF86AudioLowerVolume>", spawn "/home/sravan/.scripts/pactl.sh --lower") -- decrease volume
, ("<XF86AudioMute>", spawn "/home/sravan/.scripts/pactl.sh --mute") -- mute volume
, ("M-v", spawn "/home/sravan/.scripts/pactl.sh --rofi") -- rofi menu
-- media control
, ("<XF86AudioPlay>", spawn "/home/sravan/.scripts/playerctl.sh --play-pause") -- play / pause
, ("M-m", spawn "/home/sravan/.scripts/playerctl.sh --rofi") -- rofi menu
-- notification control
, ("M-n", spawn "/home/sravan/.scripts/dunst.sh --rofi") -- rofi menu
-- session control
, ("M-q", spawn "/home/sravan/.scripts/session.sh --rofi") -- rofi menu
, ("M-S-q", io (exitWith ExitSuccess))
-- close focused window
, ("M-S-c", kill) -- regular kill
, ("M-C-S-c", spawn "xkill") -- force kill
-- compositor control
, ("M-<Esc>", spawn "/home/sravan/.scripts/picom.sh --rofi")
-- 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 =
-- remove borders on floating windows that cover the whole screen
lessBorders OnlyScreenFloat
-- avoid struts (status bar)
$ avoidStruts ( tiled ||| grid ||| monocle )
where
-- Gaps around and between windows
-- Changes only seem to apply if I log out then in again
-- Dimensions are given as (Border top bottom right left)
mySpacing = spacingRaw False -- Only for >1 window
-- The bottom edge seems to look narrower than it is
(Border 15 15 15 15) -- Size of screen edge gaps
True -- Enable screen edge gaps
(Border 10 10 10 10) -- Size of window gaps
True -- Enable window gaps
-- default tiling algorithm partitions the screen into two panes
nmaster = 1
delta = 3/100
tiled_ratio = 1/2
tiled = mySpacing $ ResizableTall nmaster delta tiled_ratio []
-- grid
grid_ratio = 16/9
grid = mySpacing $ 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
, title =? "Picture in picture" --> doFloat
, title =? "Origin" --> doFloat
]
Automatically place floating windows using myPlacement
.
Smart placement with a preference for putting windows near the center of the screen, and with 16px gaps at the top and bottom of the screen where no window will be placed.
myPlacement = withGaps (16,0,16,0) (smart (0.5,0.5))
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.
myEventHook = ewmhDesktopsEventHook <+> fullscreenEventHook
Logging
Perform an arbitrary action on each internal state change or X event.
See the XMonad.Hooks.DynamicLog
extension for examples.
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 = return()
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
-- launches polybar
spawn "/home/sravan/.xmonad/polybar/launch.sh &"
-- launches xmonad
xmonad $ docks $ ewmh desktopConfig
{ manageHook = manageDocks <+> myManageHook <+> placeHook myPlacement <+> manageHook desktopConfig
, startupHook = myStartupHook
, layoutHook = myLayout
, borderWidth = myBorderWidth
, terminal = myTerminal
, modMask = myModMask
, normalBorderColor = myNormalBorderColor
, focusedBorderColor = myFocusedBorderColor
, handleEventHook = myEventHook
, focusFollowsMouse = myFocusFollowsMouse
, clickJustFocuses = myClickJustFocuses
, workspaces = myWorkspaces
, mouseBindings = myMouseBindings
-- , logHook = myLogHook
-- , keys = myKeys
}
`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"]
Status Bar
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%" }
Polybar
To learn more about how to configure Polybar go to https://github.com/polybar/polybar
General
Colors
[colors]
dark-gray = ${xrdb:background:#282A36}
light-gray = ${xrdb:color8:#4D4D4D}
lighter-gray = ${xrdb:color7:#BFBFBF}
white = ${xrdb:foreground:#F8F8F2}
purple = ${xrdb:color4:#BD93F9}
blue = ${xrdb:color6:#8BE9FD}
red = ${xrdb:color1:#FF5555}
pink = ${xrdb:color5:#FF79C6}
yellow = ${xrdb:color3:#F1FA8C}
green = ${xrdb:color2:#50FA7B}
orange = ${xrdb:color16:#FFB86C}
background = ${self.dark-gray}
background-alt = ${self.light-gray}
foreground = ${self.white}
foreground-alt = ${self.lighter-gray}
primary = ${self.purple}
secondary = ${self.blue}
alert = ${self.red}
; left
powermenu = ${self.blue}
xmonad-focused-foreground = ${self.background}
xmonad-focused-background = ${self.primary}
xmonad-unfocused-foreground = ${self.background}
xmonad-unfocused-background = ${self.secondary}
xmonad-urgent-foreground = ${self.foreground}
xmonad-urgent-background = ${self.alert}
xmonad-empty-foreground = ${self.foreground}
xmonad-empty-background = ${self.background}
media-playing = ${self.green}
; center
date = ${self.blue}
time = ${self.yellow}
; right
user-kernel = ${self.purple}
updates = ${self.green}
cpu = ${self.yellow}
memory = ${self.pink}
filesystem = ${self.blue}
dunst-notification-status = ${self.red}
Sizes
[sizes]
bar-height = ${xrdb:polybar.bar-height:25}
module-margin = ${xrdb:polybar.module-margin:2}
module-padding = ${xrdb:polybar.module-padding:2}
tray-maxsize = ${xrdb:polybar.tray-maxsize:15}
tray-scale = ${xrdb:polybar.tray-scale:1}
maxlen = ${xrdb:polybar.maxlen:50}
Intervals
Define module update intervals in seconds.
[intervals]
cpu = 1
date = 1
time = 1
filesystem = 900
memory = 1
updates = 900
media-playing = 1
dunst-notification-status = 1
Global Window Manager
[global/wm]
; Adjust the _NET_WM_STRUT_PARTIAL top value
; Used for top aligned bars
margin-bottom = 0
; Adjust the _NET_WM_STRUT_PARTIAL bottom value
; Used for bottom aligned bars
margin-top = 0
Bars
[bar/mybar]
; Use either of the following command to list available outputs:
; If unspecified, the application will pick the first one it finds.
; $ polybar -m | cut -d ':' -f 1
; $ xrandr -q | grep " connected" | cut -d ' ' -f1
; If no monitor is given, the primary monitor is used if it exists
monitor = ${env:MONITOR}
; Use the specified monitor as a fallback if the main one is not found.
; monitor-fallback =
; Require the monitor to be in connected state
; XRandR sometimes reports my monitor as being disconnected (when in use)
monitor-strict = false
; Use fuzzy matching for monitors (only ignores dashes -)
; Useful when monitors are named differently with different drivers.
monitor-exact = true
; Tell the Window Manager not to configure the window.
; Use this to detach the bar if your WM is locking its size/position.
; Note: With this most WMs will no longer reserve space for
; the bar and it will overlap other windows. You need to configure
; your WM to add a gap where the bar will be placed.
override-redirect = false
; Put the bar at the bottom of the screen
bottom = false
; Prefer fixed center position for the `modules-center` block.
; The center block will stay in the middle of the bar whenever
; possible. It can still be pushed around if other blocks need
; more space.
; When false, the center block is centered in the space between
; the left and right block.
fixed-center = true
; Dimension defined as pixel value (e.g. 35) or percentage (e.g. 50%),
; the percentage can optionally be extended with a pixel offset like so:
; 50%:-10, this will result in a width or height of 50% minus 10 pixels
width = 100%
height = ${sizes.bar-height}
; Offset defined as pixel value (e.g. 35) or percentage (e.g. 50%)
; the percentage can optionally be extended with a pixel offset like so:
; 50%:-10, this will result in an offset in the x or y direction
; of 50% minus 10 pixels
offset-x = 0
offset-y = 0
; Background ARGB color (e.g. #f00, #ff992a, #ddff1023)
background = ${colors.background}
; Foreground ARGB color (e.g. #f00, #ff992a, #ddff1023)
foreground = ${colors.foreground}
; Background gradient (vertical steps)
; background-[0-9]+ = #aarrggbb
; background-0 =
; Value used for drawing rounded corners
; Note: This shouldn't be used together with border-size because the border
; doesn't get rounded. For this to work you may also need to enable
; pseudo-transparency or use a compositor like compton.
; Individual top/bottom values can be defined using:
; radius-{top,bottom}
radius = 0.0
; Under-/overline pixel size and argb color
; Individual values can be defined using:
; {overline,underline}-size
; {overline,underline}-color
line-size = 0
line-color = #f00
; Values applied to all borders
; Individual side values can be defined using:
; border-{left,top,right,bottom}-size
; border-{left,top,right,bottom}-color
; The top and bottom borders are added to the bar height, so the effective
; window height is:
; height + border-top-size + border-bottom-size
; Meanwhile the effective window width is defined entirely by the width key and
; the border is placed within this area. So you effectively only have the
; following horizontal space on the bar:
; width - border-right-size - border-left-size
; border-size can be defined as pixel value (e.g. 35) or percentage (e.g. 50%),
; the percentage can optionally be extended with a pixel offset like so:
; 50%:-10, this will result in 50% minus 10 pixels. The percentage is relative
; to the monitor width or height depending on the border direction.
; border-size =
; border-color =
; Number of spaces to add at the beginning/end of the bar
; Individual side values can be defined using:
; padding-{left,right}
padding-right = ${self.module-margin}
; Number of spaces to add before/after each module
; Individual side values can be defined using:
; module-margin-{left,right}
module-margin = ${sizes.module-margin}
; Fonts are defined using <font-name>;<vertical-offset>
; Font names are specified using a fontconfig pattern.
; font-0 = NotoSans-Regular:size=8;2
; font-1 = MaterialIcons:size=10
; font-2 = Termsynu:size=8;-1
; font-3 = FontAwesome:size=10
; See the Fonts wiki page for more details
font-0 = "NotoSans Nerd Font:size=11;3"
font-1 = "MonaspiceNe NF:size=11;3"
font-2 = "DroidSansM Nerd Font:size=11;3"
font-3 = "IPAPGothic:size=11;3"
; Modules are added to one of the available blocks
; modules-left = cpu ram
; modules-center = xwindow xbacklight
; modules-right = ipc clock
modules-left = powermenu ewmh media-playing
modules-center = date time
modules-right = user-kernel updates cpu memory filesystem dunst-notification-status
; The separator will be inserted between the output of each module
separator = " "
; This value is used to add extra spacing between elements
; @deprecated: This parameter will be removed in an upcoming version
; spacing = 0
; Opacity value between 0.0 and 1.0 used on fade in/out
dim-value = 1.0
; Value to be used to set the WM_NAME atom
; If the value is empty or undefined, the atom value
; will be created from the following template: polybar-[BAR]_[MONITOR]
; NOTE: The placeholders are not available for custom values
; wm-name =
; Locale used to localize various module data (e.g. date)
; Expects a valid libc locale, for example: sv_SE.UTF-8
locale = en_US.utf8
; Position of the system tray window
; If empty or undefined, tray support will be disabled
; NOTE: A center aligned tray will cover center aligned modules
;
; Available positions:
; left
; center
; right
; none
tray-position = ${env:TRAY_POS}
; If true, the bar will not shift its
; contents when the tray changes
tray-detached = false
; Tray icon max size
tray-maxsize = ${sizes.tray-maxsize}
; DEPRECATED! Since 3.3.0 the tray always uses pseudo-transparency
; Enable pseudo transparency
; Will automatically be enabled if a fully transparent
; background color is defined using `tray-background`
; tray-transparent = false
; Background color for the tray container
; ARGB color (e.g. #f00, #ff992a, #ddff1023)
; By default the tray container will use the bar
; background color.
tray-background = ${colors.background}
; Tray offset defined as pixel value (e.g. 35) or percentage (e.g. 50%)
tray-offset-x = 0
tray-offset-y = 0
; Pad the sides of each tray icon
tray-padding = ${self.module-margin}
; Scale factor for tray clients
tray-scale = ${sizes.tray-scale}
; Restack the bar window. Fixes the issue where the
; bar is being drawn on top of fullscreen windows.
;
; Currently supported options:
; generic (works in xmonad, may work with other WMs)
; bspwm
; i3 (requires: `override-redirect = true`)
wm-restack = generic
; Set a DPI values used when rendering text
; This only affects scalable fonts
; Set this to 0 to let polybar calculate the dpi from the screen size.
; dpi =
dpi-x = ${xrdb:dpi}
dpi-y = ${xrdb:dpi}
; Enable support for inter-process messaging
; See the Messaging wiki page for more details.
enable-ipc = true
; Fallback click handlers that will be called if
; there's no matching module handler found.
; click-left =
; click-middle =
; click-right =
; scroll-up =
; scroll-down =
; double-click-left =
; double-click-middle =
; double-click-right =
; Requires polybar to be built with xcursor support (xcb-util-cursor)
; Possible values are:
; - default : The default pointer as before, can also be an empty string (default)
; - pointer : Typically in the form of a hand
; - ns-resize : Up and down arrows, can be used to indicate scrolling
cursor-click = pointer
cursor-scroll = ns-resize
Modules
Power Menu
[module/powermenu]
type = custom/text
content = " "
; "content" has the same properties as "format-NAME"
; content-background = #000
content-foreground = ${colors.powermenu}
content-padding = ${bar/mybar.module-margin}
; "click-(left|middle|right)" will be executed using "/bin/sh -c $COMMAND"
; click-left = notify-send left
; click-middle = notify-send middle
; click-right = notify-send right
click-left = "rofi -show combi"
click-right = "/home/sravan/.scripts/control-center.sh --rofi"
; "scroll-(up|down)" will be executed using "/bin/sh -c $COMMAND"
; scroll-up = notify-send scroll up
; scroll-down = notify-send scroll down
EWMH
[module/ewmh]
type = internal/xworkspaces
; Only show workspaces defined on the same output as the bar
;
; Useful if you want to show monitor specific workspaces
; on different bars
;
; Default: false
pin-workspaces = false
; Create click handler used to focus desktop
; Default: true
enable-click = true
; Create scroll handlers used to cycle desktops
; Default: true
enable-scroll = true
; icon-[0-9]+ = <desktop-name>;<icon>
; NOTE: The desktop name needs to match the name configured by the WM
; You can get a list of the defined desktops using:
; $ xprop -root _NET_DESKTOP_NAMES
; Note: Neither <desktop-name> nor <icon> can contain a semicolon (;)
; icon-0 = code;♚
; icon-1 = office;♛
; icon-2 = graphics;♜
; icon-3 = mail;♝
; icon-4 = web;♞
; icon-default = ♟
icon-0 = 1; ₁
icon-1 = 2; ₂
icon-2 = 3; ₃
icon-3 = 4; ₄
icon-4 = 5; ₅
icon-5 = 6; ₆
icon-6 = 7; ₇
icon-7 = 8; ₈
icon-8 = 9; ₉
; Available tags:
; <label-monitor>
; <label-state> - gets replaced with <label-(active|urgent|occupied|empty)>
; Default: <label-state>
format = <label-state>
; Available tokens:
; %name%
; Default: %name%
label-monitor = %name%
; Available tokens:
; %name%
; %icon%
; %index%
; Default: %icon% %name%
label-active = %icon%
label-active-foreground = ${colors.xmonad-focused-foreground}
label-active-background = ${colors.xmonad-focused-background}
label-active-underline = ${colors.xmonad-focused-background}
label-active-padding = ${sizes.module-padding}
; Available tokens:
; %name%
; %icon%
; %index%
; Default: %icon% %name%
label-occupied = %icon%
label-occupied-foreground = ${colors.xmonad-unfocused-foreground}
label-occupied-background = ${colors.xmonad-unfocused-background}
label-occupied-underline = ${colors.xmonad-unfocused-background}
label-occupied-padding = ${sizes.module-padding}
; Available tokens:
; %name%
; %icon%
; %index%
; Default: %icon% %name%
label-urgent = %icon%
label-urgent-foreground = ${colors.xmonad-urgent-foreground}
label-urgent-background = ${colors.xmonad-urgent-background}
label-urgent-underline = ${colors.xmonad-urgent-background}
label-urgent-padding = ${sizes.module-padding}
; Available tokens:
; %name%
; %icon%
; %index%
; Default: %icon% %name%
label-empty = %icon%
label-empty-foreground = ${colors.xmonad-empty-foreground}
label-empty-background = ${colors.xmonad-empty-background}
label-empty-underline = ${colors.xmonad-empty-background}
label-empty-padding = ${sizes.module-padding}
Media Playing (Playerctl)
Module
[module/media-playing]
type = custom/script
; Available tokens:
; %counter%
; Command to be executed (using "/bin/sh -c [command]")
exec = ~/.xmonad/polybar/scripts/get-media-playing.sh
; Conditional command that, if defined, needs to exit successfully
; before the main exec command is invoked.
; Default: ""
; exec-if = pgrep -x myservice
; Will the script output continous content?
; Default: false
tail = false
; Seconds to sleep between updates
; Default: 5 (0 if `tail = true`)
interval = ${intervals.media-playing}
; Available tags:
; <output> - deprecated
; <label> (default)
format = <label>
; format-background = ${colors.background}
; format-foreground =
; format-padding = 4
; Available tokens:
; %output%
; Default: %output%
label = %output%
label-foreground = ${colors.media-playing}
label-maxlen = ${sizes.maxlen}
; Available tokens:
; %counter%
; %pid%
;
; "click-(left|middle|right)" will be executed using "/bin/sh -c [command]"
click-left = "/home/sravan/.scripts/playerctl.sh --play-pause"
; click-middle = echo middle %counter%
click-right = "/home/sravan/.scripts/playerctl.sh --change"
; double-click-left = echo double left %counter%
; double-click-middle = echo double middle %counter%
; double-click-right = echo double right %counter%
; Available tokens:
; %counter%
; %pid%
;
; "scroll-(up|down)" will be executed using "/bin/sh -c [command]"
scroll-up = "/home/sravan/.scripts/playerctl.sh --next"
scroll-down = "/home/sravan/.scripts/playerctl.sh --prev"
Script
mediaStatus=$(playerctl --player=playerctld metadata 2>&1)
if [[ "$mediaStatus" == "No player could handle this command" ]]; then
echo " N/A"
else
artist=$(playerctl --player=playerctld metadata --format '{{ artist }}')
title=$(playerctl --player=playerctld metadata --format '{{ title }}')
status=$(playerctl --player=playerctld metadata --format '{{ status }}')
if [[ $status == "Paused" ]]; then
status_icon=" "
elif [[ $status == "Playing" ]]; then
status_icon=" "
fi
echo "$status_icon $artist - $title"
fi
Date
[module/date]
type = internal/date
; Seconds to sleep between updates
; Default: 1.0
interval = ${intervals.date}
; See "https://en.cppreference.com/w/cpp/io/manip/put_time" for details on how to format the date string
; NOTE: if you want to use syntax tags here you need to use %%{...}
date = %a %x
; Optional time format
; time = %X
; if `date-alt` or `time-alt` is defined, clicking
; the module will toggle between formats
date-alt = %A, %B %d, %Y
; time-alt = %H:%M:%S
; Available tags:
; <label> (default)
format = <label>
; Available tokens:
; %date%
; %time%
; Default: %date%
label = " %date%"
; label-font = 3
label-foreground = ${colors.date}
Time
[module/time]
type = internal/date
; Seconds to sleep between updates
; Default: 1.0
interval = ${intervals.time}
; See "https://en.cppreference.com/w/cpp/io/manip/put_time" for details on how to format the date string
; NOTE: if you want to use syntax tags here you need to use %%{...}
; date = %a %x
; Optional time format
time = %X
; if `date-alt` or `time-alt` is defined, clicking
; the module will toggle between formats
; date-alt = %A, %B %d, %Y
time-alt = UTC%z (%Z)
; Available tags:
; <label> (default)
format = <label>
; Available tokens:
; %date%
; %time%
; Default: %date%
label = " %time%"
; label-font = 3
label-foreground = ${colors.time}
User / Kernel
[module/user-kernel]
type = custom/ipc
; Define the command to be executed when the hook is triggered
; Available tokens:
; %pid% (id of the parent polybar process)
hook-0 = echo " $(whoami)"
hook-1 = echo " $(uname -r)"
; Hook to execute on launch. The index is 1-based and using
; the example below (2) `whoami` would be executed on launch.
; If 0 is specified, no hook is run on launch
; Default: 0
initial = 2
; Available tags:
; <output> (default)
format = <output>
format-foreground = ${colors.user-kernel}
format-background = ${colors.background}
; Mouse actions
; Available tokens:
; %pid% (id of the parent polybar process)
click-left = polybar-msg -p %pid% hook user-kernel 1 &
; click-middle =
click-right = polybar-msg -p %pid% hook user-kernel 2 &
; scroll-up =
; scroll-down =
; double-click-left =
; double-click-right =
Updates (Pacman)
Module
[module/updates]
type = custom/script
; Available tokens:
; %counter%
; Command to be executed (using "/bin/sh -c [command]")
exec = ~/.xmonad/polybar/scripts/updates-pacman-aurhelper.sh
; Conditional command that, if defined, needs to exit successfully
; before the main exec command is invoked.
; Default: ""
; exec-if = pgrep -x myservice
; Will the script output continous content?
; Default: false
tail = false
; Seconds to sleep between updates
; Default: 5 (0 if `tail = true`)
interval = ${intervals.updates}
; Available tags:
; <output> - deprecated
; <label> (default)
format = <label>
; format-background = ${colors.background}
; format-foreground =
; format-padding = 4
; Available tokens:
; %output%
; Default: %output%
label = %output%
label-foreground = ${colors.updates}
; Available tokens:
; %counter%
; %pid%
;
; "click-(left|middle|right)" will be executed using "/bin/sh -c [command]"
; click-left = echo left %counter%
; click-middle = echo middle %counter%
click-right = alacritty --hold -e paru -Syu &
; double-click-left = echo double left %counter%
; double-click-middle = echo double middle %counter%
; double-click-right = echo double right %counter%
; Available tokens:
; %counter%
; %pid%
;
; "scroll-(up|down)" will be executed using "/bin/sh -c [command]"
; scroll-up = echo scroll up %counter%
; scroll-down = echo scroll down %counter%
Script
if ! updates_arch=$(checkupdates 2> /dev/null | wc -l ); then
updates_arch=0
fi
# if ! updates_aur=$(yay -Qum 2> /dev/null | wc -l); then
if ! updates_aur=$(paru -Qum 2> /dev/null | wc -l); then
# if ! updates_aur=$(cower -u 2> /dev/null | wc -l); then
# if ! updates_aur=$(trizen -Su --aur --quiet | wc -l); then
# if ! updates_aur=$(pikaur -Qua 2> /dev/null | wc -l); then
# if ! updates_aur=$(rua upgrade --printonly 2> /dev/null | wc -l); then
updates_aur=0
fi
updates=$((updates_arch + updates_aur))
# if [ "$updates" -gt 0 ]; then
# echo "# $updates"
# else
# echo ""
# fi
echo "$updates"
CPU
[module/cpu]
type = internal/cpu
; Seconds to sleep between updates
; Default: 1
interval = ${intervals.cpu}
; Available tags:
; <label> (default)
; <bar-load>
; <ramp-load>
; <ramp-coreload>
format = %{A3:alacritty -e bpytop &:} <label> %{A}
; Available tokens:
; %percentage% (default) - total cpu load averaged over all cores
; %percentage-sum% - Cumulative load on all cores
; %percentage-cores% - load percentage for each core
; %percentage-core[1-9]% - load percentage for specific core
label = %percentage%%
label-foreground = ${colors.cpu}
; Spacing between individual per-core ramps
ramp-coreload-spacing = 1
ramp-coreload-0 = ▁
ramp-coreload-1 = ▂
ramp-coreload-2 = ▃
ramp-coreload-3 = ▄
ramp-coreload-4 = ▅
ramp-coreload-5 = ▆
ramp-coreload-6 = ▇
ramp-coreload-7 = █
ramp-coreload-foreground = ${colors.cpu}
Memory
[module/memory]
type = internal/memory
; Seconds to sleep between updates
; Default: 1
interval = ${intervals.memory}
; Available tags:
; <label> (default)
; <bar-used>
; <bar-free>
; <ramp-used>
; <ramp-free>
; <bar-swap-used>
; <bar-swap-free>
; <ramp-swap-used>
; <ramp-swap-free>
format = %{A3:alacritty -e bpytop &:} <label> %{A}
; Available tokens:
; %percentage_used% (default)
; %percentage_free%
; %gb_used%
; %gb_free%
; %gb_total%
; %mb_used%
; %mb_free%
; %mb_total%
; %percentage_swap_used%
; %percentage_swap_free%
; %mb_swap_total%
; %mb_swap_free%
; %mb_swap_used%
; %gb_swap_total%
; %gb_swap_free%
; %gb_swap_used%
label = %percentage_used%%
label-foreground = ${colors.memory}
; Only applies if <bar-used> is used
bar-used-indicator =
bar-used-width = 50
bar-used-foreground-0 = #55aa55
bar-used-foreground-1 = #557755
bar-used-foreground-2 = #f5a70a
bar-used-foreground-3 = #ff5555
bar-used-fill = ▐
bar-used-empty = ▐
bar-used-empty-foreground = #444444
; Only applies if <ramp-used> is used
ramp-used-0 = ▁
ramp-used-1 = ▂
ramp-used-2 = ▃
ramp-used-3 = ▄
ramp-used-4 = ▅
ramp-used-5 = ▆
ramp-used-6 = ▇
ramp-used-7 = █
ramp-used-foreground = ${colors.memory}
; Only applies if <ramp-free> is used
ramp-free-0 = ▁
ramp-free-1 = ▂
ramp-free-2 = ▃
ramp-free-3 = ▄
ramp-free-4 = ▅
ramp-free-5 = ▆
ramp-free-6 = ▇
ramp-free-7 = █
ramp-free-foreground = ${colors.memory}
Filesystem
[module/filesystem]
type = internal/fs
; Mountpoints to display
mount-0 = /home
; Seconds to sleep between updates
; Default: 30
interval = ${intervals.filesystem}
; Display fixed precision values
; Default: false
fixed-values = true
; Spacing between entries
; Default: 2
spacing = ${bar/mybar.module-margin}
; Available tags:
; <label-mounted> (default)
; <bar-free>
; <bar-used>
; <ramp-capacity>
format-mounted = %{A3:filelight &:} <label-mounted> %{A}
; Available tags:
; <label-unmounted> (default)
format-unmounted = %{A3:gnome-disks &:} <label-unmounted> %{A}
; Available tokens:
; %mountpoint%
; %type%
; %fsname%
; %percentage_free%
; %percentage_used%
; %total%
; %free%
; %used%
; Default: %mountpoint% %percentage_free%%
label-mounted = %percentage_used%%
label-mounted-foreground = ${colors.filesystem}
; Available tokens:
; %mountpoint%
; Default: %mountpoint% is not mounted
label-unmounted = %mountpoint% is not mounted
label-unmounted-foreground = ${colors.filesystem}
Dunst Notification Status
Module
[module/dunst-notification-status]
type = custom/script
; Available tokens:
; %counter%
; Command to be executed (using "/bin/sh -c [command]")
exec = ~/.xmonad/polybar/scripts/dunst-notification-status.sh
; Conditional command that, if defined, needs to exit successfully
; before the main exec command is invoked.
; Default: ""
; exec-if = pgrep -x myservice
; Will the script output continous content?
; Default: false
tail = false
; Seconds to sleep between updates
; Default: 5 (0 if `tail = true`)
interval = ${intervals.dunst-notification-status}
; Available tags:
; <output> - deprecated
; <label> (default)
format = <label>
; format-background = ${colors.background}
; format-foreground =
; format-padding = 4
; Available tokens:
; %output%
; Default: %output%
label = %output%
label-foreground = ${colors.dunst-notification-status}
; label-maxlen =
; Available tokens:
; %counter%
; %pid%
;
; "click-(left|middle|right)" will be executed using "/bin/sh -c [command]"
click-left = "/home/sravan/.scripts/dunst.sh --dnd"
; click-middle = echo middle %counter%
click-right = "/home/sravan/.scripts/dunst.sh --history"
; double-click-left = echo double left %counter%
; double-click-middle = echo double middle %counter%
; double-click-right = echo double right %counter%
; Available tokens:
; %counter%
; %pid%
;
; "scroll-(up|down)" will be executed using "/bin/sh -c [command]"
; scroll-up =
; scroll-down =
Script
# Check if dunst is running
if pgrep -x "dunst" > /dev/null
then
is_paused=$(dunstctl is-paused)
if [[ $is_paused == 'false' ]]; then
status_icon=" on"
elif [[ $is_paused == 'true' ]]; then
status_icon=" off"
fi
else
status_icon=" off"
fi
echo $status_icon
Launch Script
BAR="mybar"
CONFIG="~/.xmonad/polybar/config.ini"
NUM_MONITORS=0
CONNECTED_MONITORS=$(xrandr --query | grep " connected" | cut -d" " -f1)
TRAY_POS="right"
pkill polybar
while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done
rm /tmp/polybar.pids
sleep 1
for m in $CONNECTED_MONITORS; do
let "NUM_MONITORS+=1"
done
if [ $NUM_MONITORS == 1 ]; then
# Launch on only monitor w/ systray
MONITOR=$CONNECTED_MONITORS TRAY_POS=$TRAY_POS polybar --reload -c $CONFIG $BAR &
else
PRIMARY=$(xrandr --query | grep " connected" | grep "primary" | cut -d" " -f1)
OTHERS=$(xrandr --query | grep " connected" | grep -v "primary" | cut -d" " -f1)
# Launch on primary monitor w/ systray
MONITOR=$PRIMARY TRAY_POS=$TRAY_POS polybar --reload -c $CONFIG $BAR &
sleep 1
# Launch on all other monitors w/o systray
for m in $OTHERS; do
MONITOR=$m TRAY_POS=none polybar --reload -c $CONFIG $BAR &
done
fi
echo "$!" >>/tmp/polybar.pids