lib/LaNinpreConfig.hs (view raw)
1{-# OPTIONS_HADDOCK ignore-exports, prune #-}
2----------------------------------------------------------------------
3-- |
4-- Module : LaNinpreConfig
5-- Description : personal stuff for xmonad
6-- Maintainer : la-ninpre
7--
8-- this module exists because i find it more convenient to manage some things
9-- from here instead of doing it right in xmonad config
10--
11----------------------------------------------------------------------
12
13module LaNinpreConfig (
14 -- * global
15 -- $global
16 myFonts,
17 myColor,
18 myModMask,
19 myTerminal,
20 myBrowser,
21 myGeminiClient,
22 myFileMgr,
23 myMocp,
24 myEditor,
25 myBorderWidth,
26 myNormColor,
27 myFocusColor,
28 myAppGrid,
29 myWorkspaces,
30 myScratchPads,
31 myManageHook,
32 myStartupHook
33 ) where
34
35import Data.List
36import Data.Map as M
37import Data.Maybe
38import Data.Monoid
39
40import XMonad
41import qualified XMonad.StackSet as W
42import XMonad.Hooks.ManageHelpers
43import XMonad.Hooks.SetWMName
44import XMonad.Util.NamedScratchpad
45import XMonad.Util.SpawnOnce
46
47-- $global
48--
49-- constants and functions starting with \'my\' are exported and used in
50-- xmonad config.
51
52-- * constants
53
54-- $constants
55-- these are set up to avoid unnecessary repetition of replacements, when
56-- things change.
57
58-- ** fonts
59--
60-- $fonts
61-- default fonts and helper functions for them.
62
63-- | default lato font
64fontLatoDef = fontXft "Lato" "regular" 14
65
66-- | font for @ShowWMName@
67--
68-- normal variant
69--
70-- > fontSWN = fontXft "Press Start 2P" "regular" 60
71--
72-- sitelen pona pona variant
73--
74-- > fontSWN = fontXft "sitelen\\-pona" "regular" 80
75fontSWN = fontXft "linja pona" "regular" 80
76
77-- | fonts list
78myFonts :: [String]
79myFonts = [ fontLatoDef
80 , fontSWN
81 ]
82
83-- *** helper functions
84--
85-- | font constructor
86--
87-- it is just a helper function to simplify the process of specifying font
88-- with xft.
89fontXft :: String -- ^ font family
90 -> String -- ^ font style
91 -> Int -- ^ font style
92 -> String
93
94fontXft font style size = intercalate ":" [ "xft"
95 , font
96 , style
97 , "size=" ++ show size
98 , "antialias=true"
99 , "hinting=true"
100 ]
101
102
103-- ** colors
104
105-- $colorTheme
106--
107-- > bg #19191a
108-- > fg #cadcde
109-- > grey0 #232324
110-- > grey1 #363638
111-- > grey2 #66666a
112-- > black #393838
113-- > red #c74444
114-- > green #7f9848
115-- > yellow #d7a06d
116-- > blue #4e96d5
117-- > magenta #bc5fa7
118-- > cyan #55b795
119-- > white #c3b2f7
120-- > black-bright #5a514b
121-- > red-bright #ed7c68
122-- > green-bright #c7ea76
123-- > yellow-bright #ffdb9d
124-- > blue-bright #a6d5fe
125-- > magenta-bright #edbbe9
126-- > cyan-bright #7fe2c5
127-- > white-bright #e2d6ff
128
129-- | color theme structure
130myColorTheme :: [(String,String)]
131myColorTheme = [ ("bg", "#19191a")
132 , ("fg", "#cadcde")
133 , ("gray0", "#232324")
134 , ("gray1", "#363638")
135 , ("gray2", "#5c5c60")
136 , ("gray3", "#66666a")
137 , ("gray4", "#ececf0")
138 , ("black", "#393838")
139 , ("red", "#c74444")
140 , ("green", "#7f9848")
141 , ("yellow", "#d7a06d")
142 , ("blue", "#4e96d5")
143 , ("magenta", "#bc5fa7")
144 , ("cyan", "#55b795")
145 , ("white", "#c3b2f7")
146 , ("black-bright", "#5a514b")
147 , ("red-bright", "#ed7c68")
148 , ("green-bright", "#c7ea76")
149 , ("yellow-bright", "#ffdb9d")
150 , ("blue-bright", "#a6d5fe")
151 , ("magenta-bright", "#edbbe9")
152 , ("cyan-bright", "#7fe2c5")
153 , ("white-bright", "#e2d6ff")
154 ]
155
156-- | unfocused window border colour
157myNormColor :: String
158myNormColor = myColor "gray0"
159
160-- | focused window border colour
161myFocusColor :: String
162myFocusColor = myColor "blue"
163
164-- *** helper functions
165--
166-- | get color from color theme
167myColor :: String -> String
168myColor c = fromMaybe "" (M.lookup c theme)
169 where
170 theme = fromList myColorTheme
171
172
173-- ** software constants
174--
175-- | set terminal emulator
176myTerminal :: String
177myTerminal = "alacritty"
178
179-- | set default browser
180myBrowser :: String
181myBrowser = "brave"
182
183-- | set gemini client
184myGeminiClient :: String
185myGeminiClient = "amfora"
186
187-- | set file manager
188myFileMgr :: String
189myFileMgr = "thunar"
190
191-- | music on console
192--
193-- this is to avoid spamming strings everywhere. @moc@ doesn't comply with
194-- XDG_CONFIG_HOME, so we force it to do so.
195myMocp :: String
196myMocp = "mocp -M '~/.config/moc'"
197
198-- | set editor
199myEditor :: String
200myEditor = myTerminal ++ " -e vim"
201
202-- ** other constants
203--
204-- | set windows key as modkey
205myModMask :: KeyMask
206myModMask = mod4Mask
207
208-- | specify border width
209myBorderWidth :: Dimension
210myBorderWidth = 1
211
212-- | app grid for @GridSelect@ layout
213myAppGrid :: [(String,String)]
214myAppGrid = [ ("discord", "discord")
215 , ("steam", "steam")
216 , ("cadence", "cadence")
217 , ("blender", "blender")
218 , ("inkscape", "inkscape")
219 , ("obs", "obs")
220 , ("gimp", "gimp")
221 , ("element", "element-desktop")
222 , ("ardour", "ardour6")
223 , ("kdenlive", "kdenlive")
224 , ("writer", "lowriter")
225 ]
226
227-- * hooks
228--
229-- ** startup hook
230--
231-- $startupHook
232--
233-- start things at login.
234
235-- | actual instance
236myStartupHook :: X ()
237myStartupHook = do
238 spawnOnce "dunst &"
239 spawnOnce "lxsession &"
240 spawnOnce "picom &"
241 spawnOnce "nm-applet &"
242 spawnOnce "volumeicon &"
243 spawnOnce "setxkbmap -layout us,ru -option 'grp:alt_shift_toggle'"
244 spawnOnce "kbdd"
245 spawnOnce ("trayer --edge top "
246 ++ "--align right "
247 ++ "--widthtype request "
248 ++ "--SetDockType true --SetPartialStrut true --expand false "
249 ++ "--monitor 0 --transparent true --alpha 0 "
250 ++ "--tint 0x19191a --height 24 &"
251 )
252 spawnOnce "nitrogen --restore &"
253 setWMName "LG3D"
254
255-- ** manage hook
256--
257-- $managehook
258--
259-- @doFloat@ forces a window to float. useful for dialog boxes and such.
260-- using @doShift (myWorkspaces !! 7)@ sends program to workspace 8
261-- i'm doing it this way because otherwise i would have to write out the full
262-- name of my workspaces and the names would be very long if using clickable workspaces.
263
264-- | manage hook
265myManageHook :: Query (Endo WindowSet)
266myManageHook = composeAll
267 [ className =? "confirm" --> doFloat
268 , className =? "file_progress" --> doFloat
269 , className =? "dialog" --> doFloat
270 , className =? "download" --> doFloat
271 , className =? "error" --> doFloat
272 , className =? "Gimp" --> doFloat
273 , className =? "notification" --> doFloat
274 , className =? "pinentry-gtk-2" --> doFloat
275 , className =? "splash" --> doFloat
276 , className =? "toolbar" --> doFloat
277 , className =? "Cadence" --> doFloat
278 , className =? "Steam" --> doFloat
279 , className =? "Image Lounge" --> doFloat
280 , title =? "Oracle VM VirtualBox Manager" --> doFloat
281 -- web workspace
282 , title =? "Mozilla Firefox" --> doShift ( myWorkspaces !! 1 )
283 , className =? "Brave-browser" --> doShift ( myWorkspaces !! 1 )
284 , className =? "amfora" --> doShift ( myWorkspaces !! 1 )
285 , className =? "qutebrowser" --> doShift ( myWorkspaces !! 1 )
286 -- doc workspace
287 , className =? "Geary" --> doShift ( myWorkspaces !! 3 )
288 , className =? "libreoffice-writer" --> doShift ( myWorkspaces !! 3 )
289 , className =? "libreoffice-impress" --> doShift ( myWorkspaces !! 3 )
290 -- vm workspace
291 , className =? "VirtualBox Manager" --> doShift ( myWorkspaces !! 4 )
292 -- chat workspace
293 , className =? "discord" --> doShift ( myWorkspaces !! 5 )
294 , className =? "TelegramDesktop" --> doShift ( myWorkspaces !! 5 )
295 , className =? "Element" --> doShift ( myWorkspaces !! 5 )
296 , className =? "Steam" --> doShift ( myWorkspaces !! 5 )
297 -- full workspace
298 , isFullscreen --> doShift ( myWorkspaces !! 6 )
299 -- vid workspace
300 , className =? "Deadbeef" --> doShift ( myWorkspaces !! 7 )
301 , appName =? "mpv" --> doShift ( myWorkspaces !! 7 )
302 , className =? "vlc" --> doShift ( myWorkspaces !! 7 )
303 -- gfx workspace
304 , className =? "Gimp" --> doShift ( myWorkspaces !! 8 )
305 , className =? "Blender" --> doShift ( myWorkspaces !! 8 )
306 , className =? "obs" --> doShift ( myWorkspaces !! 8 )
307 , isFullscreen --> doFullFloat
308 ] <+> namedScratchpadManageHook myScratchPads
309
310-- * scratchpads
311--
312-- $scratchpads
313--
314-- currently i have:
315--
316-- * plain terminal scratchpad
317--
318-- * music on console
319--
320-- * calculator (qalculate-gtk)
321--
322-- * mpv instance that plays playlist in @~\/Video\/sp_playlist.m3u@
323
324-- | scratchpad list
325myScratchPads :: [NamedScratchpad]
326myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
327 , NS "mocp" spawnMocp findMocp manageMocp
328 , NS "calculator" spawnCalc findCalc manageCalc
329 , NS "mpvfloat" spawnMpv findMpv manageMpv
330 ]
331 where
332 -- terminal
333 spawnTerm = myTerminal ++ " -t scratchpad"
334 findTerm = title =? "scratchpad"
335 manageTerm = customFloating $ W.RationalRect l t w h
336 where
337 h = 0.9
338 w = 0.9
339 t = 0.95 - h
340 l = 0.95 - w
341 -- music on console
342 spawnMocp = myTerminal ++ " -t mocp -e " ++ myMocp
343 findMocp = title =? "mocp"
344 manageMocp = customFloating $ W.RationalRect l t w h
345 where
346 h = 0.9
347 w = 0.9
348 t = 0.95 - h
349 l = 0.95 - w
350 -- calculator
351 spawnCalc = "qalculate-gtk"
352 findCalc = className =? "Qalculate-gtk"
353 manageCalc = customFloating $ W.RationalRect l t w h
354 where
355 h = 0.5
356 w = 0.4
357 t = 0.75 - h
358 l = 0.70 - w
359 -- mpv scratchpad to watch some stuff listed in ~/Video/sp_playlist.m3u
360 spawnMpv = "mpv --pause -x11-name mpv-sp ~/Video/sp_playlist.m3u"
361 ++ mpvGeometry mpvPercentage mpvPercentage
362 findMpv = appName =? "mpv-sp"
363 manageMpv = customFloating $ W.RationalRect l t w h
364 where
365 h = mpvPercentage
366 w = mpvPercentage
367 t = 0.03
368 l = 0.996 - w
369
370-- ** helper functions
371--
372-- | percentage of mpv scratchpad at start
373mpvPercentage :: Rational
374mpvPercentage = 1/4
375
376-- | mpv needs geometry of window at start, so it won't resize itself, when
377-- playing next video on a playlist
378mpvGeometry :: RealFrac a
379 => a -- ^ relative height of window
380 -> a -- ^ relative width of window
381 -> String
382
383mpvGeometry h w = " --geometry=" ++ (show pw) ++ "x" ++ (show ph)
384 where
385 pw = ceiling (1920 * w)
386 ph = ceiling (1080 * h)
387
388-- * workspaces
389--
390-- $workspaces
391--
392-- i've got three ways of specifying them. first one is pretty close to the
393-- original dt's config. second is using sitelen pona pona font by jackhumbert
394-- (check it out [here](https://jackhumbert.github.io/sitelen-pona-pona/)).
395-- and third one is using linja pona font by jan same
396-- (check it out [here](http://musilili.net/linja-pona/)).
397--
398-- * normal variant
399--
400-- > myWorkspaces = [ "dev"
401-- > , "www"
402-- > , "sys"
403-- > , "doc"
404-- > , "vm"
405-- > , "chat"
406-- > , "full"
407-- > , "vid"
408-- > , "gfx"
409-- > ]
410--
411-- * one using sitelen pona pona by jackhumbert
412--
413-- this is specified with actual glyph codes because xmobar
414-- don't allow for ligatures and otf features.
415--
416-- > myWorkspaces = [ "\xee3d" -- nanpa
417-- > , "\xee3b" -- musi
418-- > , "\xee49" -- pali
419-- > , "\xee2a" -- lipu
420-- > , "\xee53" -- poki
421-- > , "\xee6c" -- toki
422-- > , "\xee63" -- suli
423-- > , "\xee60" -- sitelen
424-- > , "\xee1e" -- kule
425-- > ]
426
427-- | workspaces container
428myWorkspaces = [ "\xe661\xe921" -- sona nanpa
429 , "\xe63b" -- musi
430 , "\xe649" -- pali
431 , "\xe62a\xf105" -- lipu ale
432 , "\xe653\xf115" -- poki ilo
433 , "\xe66c" -- toki
434 , "\xe62a\xf200" -- lipu suli
435 , "\xf010\xe915" -- sitelen tawa
436 , "\xf010\xf107" -- sitelen ante
437 ]