diff --git a/.bashrc b/.bashrc index 17950ec8..bb24e265 100755 --- a/.bashrc +++ b/.bashrc @@ -1,27 +1,29 @@ # # ~/.bashrc -export PATH=$PATH:~/.cabal/bin -#export PATH=$PATH:~/.local/bin + +if [ -d "$HOME/.local/bin" ] ; then + PATH="$PATH:$HOME/.local/bin" +fi + +export PATH=$PATH:~/.local/bin alias lol="sudo sh -c 'sysctl -w abi.vsyscall32=0'" alias dired="emacsclient -c -nw -a '' --eval '(dired nil)'" alias update-grub="sudo grub-mkconfig -o /boot/grub/grub.cfg" alias update-xmonad="yay -S xmonad-git xmonad-contrib-git xmobar-git" alias git-python='/usr/bin/git --git-dir=$HOME/devel/python/python-bits-and-bobs --work-tree=$HOME/devel/python' - alias rm='echo "This is not the command you are looking for."; false' alias tp='trash-put' alias te='trash-empty' alias tl='trash-list' alias tre='trash-restore' alias tpm='trash-rm' - alias mpv='mpv --title="mpv"' - alias dot='/usr/bin/git --git-dir=$HOME/.dots --work-tree=$HOME' dot config --local status.showUntrackedFiles no -#export PATH="$PATH:$(ruby -e 'print Gem.user_dir')/bin" -#export GEM_HOME=$(ruby -e 'print Gem.user_dir') -[ -f "/home/tstarr/.ghcup/env" ] && source "/home/tstarr/.ghcup/env" # ghcup-env + + +# added by Anaconda3 2.5.0 installer +#export PATH="/home/tstarr/anaconda3/bin:$PATH" diff --git a/.config/fish/fish_variables b/.config/fish/fish_variables deleted file mode 100644 index fa8bff91..00000000 --- a/.config/fish/fish_variables +++ /dev/null @@ -1,32 +0,0 @@ -# This file contains fish universal variable definitions. -# VERSION: 3.0 -SETUVAR __fish_initialized:3100 -SETUVAR fish_color_autosuggestion:555\x1ebrblack -SETUVAR fish_color_cancel:\x2dr -SETUVAR fish_color_command:005fd7 -SETUVAR fish_color_comment:990000 -SETUVAR fish_color_cwd:green -SETUVAR fish_color_cwd_root:red -SETUVAR fish_color_end:009900 -SETUVAR fish_color_error:ff0000 -SETUVAR fish_color_escape:00a6b2 -SETUVAR fish_color_history_current:\x2d\x2dbold -SETUVAR fish_color_host:normal -SETUVAR fish_color_host_remote:yellow -SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue -SETUVAR fish_color_normal:normal -SETUVAR fish_color_operator:00a6b2 -SETUVAR fish_color_param:00afff -SETUVAR fish_color_quote:999900 -SETUVAR fish_color_redirection:00afff -SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack -SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack -SETUVAR fish_color_status:red -SETUVAR fish_color_user:brgreen -SETUVAR fish_color_valid_path:\x2d\x2dunderline -SETUVAR fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell\x0aType\x20\x60help\x60\x20for\x20instructions\x20on\x20how\x20to\x20use\x20fish -SETUVAR fish_key_bindings:fish_default_key_bindings -SETUVAR fish_pager_color_completion:\x1d -SETUVAR fish_pager_color_description:B3A06D\x1eyellow -SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline -SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan diff --git a/.config/qtile/config.py b/.config/qtile/config.py index b6dae723..e8fe4611 100644 --- a/.config/qtile/config.py +++ b/.config/qtile/config.py @@ -5,6 +5,7 @@ from settings.layouts import layouts, floating_layout from settings.widgets import widget_defaults, extension_defaults from settings.screens import screens from settings.mouse import mouse +from settings.rules import dgroups_app_rules from settings.path import qtile_path from os import path diff --git a/.config/qtile/settings/keys.py b/.config/qtile/settings/keys.py index d3279713..06d6a349 100644 --- a/.config/qtile/settings/keys.py +++ b/.config/qtile/settings/keys.py @@ -1,6 +1,7 @@ from libqtile.config import EzKey from libqtile.command import lazy from libqtile import qtile +import settings.traverse as traverse # Set mod key to the "windows" key mod = "mod4" @@ -28,10 +29,10 @@ keys = [EzKey(k[0], *k[1:]) for k in [ # ------ Movement ------ # # Navigate between windows - ("M-h", lazy.layout.left()), - ("M-j", lazy.layout.down()), - ("M-k", lazy.layout.up()), - ("M-l", lazy.layout.right()), + ("M-h", lazy.function(traverse.left)), + ("M-j", lazy.function(traverse.down)), + ("M-k", lazy.function(traverse.up)), + ("M-l", lazy.function(traverse.right)), # Switch windows ("M-S-", lazy.function(switch_screens)), # Switch focus between two screens diff --git a/.config/qtile/settings/layouts.py b/.config/qtile/settings/layouts.py index d6240085..c9ada0c0 100644 --- a/.config/qtile/settings/layouts.py +++ b/.config/qtile/settings/layouts.py @@ -1,5 +1,6 @@ from libqtile import layout from settings.wal import wal +from libqtile.config import Match # Layout configs layout_conf = { @@ -23,9 +24,9 @@ layouts = [ # Define floating rules floating_layout = layout.Floating( float_rules=[ - {'wmclass': 'Steam'}, - {'wmclass': 'Wine'}, - {'wmclass': 'discord'}, + Match('wmclass', 'Steam'), + Match('wmclass', 'Wine'), + Match('wmclass', 'discord'), ], border_focus=wal['colors']['color2'], border_width=1, diff --git a/.config/qtile/settings/rules.py b/.config/qtile/settings/rules.py new file mode 100644 index 00000000..8574204a --- /dev/null +++ b/.config/qtile/settings/rules.py @@ -0,0 +1,27 @@ +from libqtile.config import Match, Rule +from libqtile import hook + +dgroups_app_rules = [Rule(Match(wm_type=["confirm", + "download", + "notification", + "toolbar", + "splash", + "dialog", + "error", + "file_progress", + "confirmreset", + "makebranch", + "maketag", + "branchdialog", + "pinentry", + "sshaskpass"]), + float=True), + Rule(Match(wm_class=["lutris", "league of legends.exe", "leagueclientux.exe"]), + float=True, + break_on_match=True)] +@hook.subscribe.client_new +def floating_dialogs(window): + dialog = window.window.get_wm_type() == 'dialog' + transient = window.window.get_wm_transient_for() + if dialog or transient: + window.floating = True diff --git a/.config/qtile/settings/screens.py b/.config/qtile/settings/screens.py index 8eef6ee3..20bfcd1a 100644 --- a/.config/qtile/settings/screens.py +++ b/.config/qtile/settings/screens.py @@ -1,8 +1,12 @@ from libqtile.config import Screen -from libqtile import bar +from libqtile import bar, widget from settings.widgets import primary_widgets # Define the screens (and bars) screens = [ - Screen(top=bar.Bar(primary_widgets, size=20)) + Screen(top=bar.Bar(widgets=primary_widgets, size=20)), + Screen(top=bar.Bar([ + widget.GroupBox(), + widget.WindowName() + ], 20),) ] diff --git a/.config/qtile/settings/traverse.py b/.config/qtile/settings/traverse.py new file mode 100644 index 00000000..55e263d4 --- /dev/null +++ b/.config/qtile/settings/traverse.py @@ -0,0 +1,88 @@ +""" +This plugin exports four functions - up, down, left and right - that when called will +move window focus to the first window in that general direction. Focussing is based +entirely on position and geometry, so is independent of screens, layouts and whether +windows are floating or tiled. It can also move focus to and from empty screens. +Example usage: + import traverse + keys.extend([EzKey(k, v) for k, v in { + 'M-k': lazy.function(traverse.up) + 'M-j': lazy.function(traverse.down) + 'M-h': lazy.function(traverse.left) + 'M-l': lazy.function(traverse.right) + }.items()]) +""" + +from libqtile.config import Screen + + +def up(qtile): + _focus_window(qtile, -1, 'y') + + +def down(qtile): + _focus_window(qtile, 1, 'y') + + +def left(qtile): + _focus_window(qtile, -1, 'x') + + +def right(qtile): + _focus_window(qtile, 1, 'x') + + +def _focus_window(qtile, dir, axis): + win = None + win_wide = None + dist = 10000 + dist_wide = 10000 + cur = qtile.current_window + if not cur: + cur = qtile.current_screen + + if axis == 'x': + dim = 'width' + band_axis = 'y' + band_dim = 'height' + cur_pos = cur.x + band_min = cur.y + band_max = cur.y + cur.height + else: + dim = 'height' + band_axis = 'x' + band_dim = 'width' + band_min = cur.x + cur_pos = cur.y + band_max = cur.x + cur.width + + cur_pos += getattr(cur, dim) / 2 + + windows = [w for g in qtile.groups if g.screen for w in g.windows] + windows.extend([s for s in qtile.screens if not s.group.windows]) + + if cur in windows: + windows.remove(cur) + + for w in windows: + if isinstance(w, Screen) or not w.minimized: + pos = getattr(w, axis) + getattr(w, dim) / 2 + gap = dir * (pos - cur_pos) + if gap > 5: + band_pos = getattr(w, band_axis) + getattr(w, band_dim) / 2 + if band_min < band_pos < band_max: + if gap < dist: + dist = gap + win = w + else: + if gap < dist_wide: + dist_wide = gap + win_wide = w + + if not win: + win = win_wide + if win: + qtile.focus_screen(win.group.screen.index) + win.group.focus(win, True) + if not isinstance(win, Screen): + win.focus(False) diff --git a/.config/qtile/settings/widgets.py b/.config/qtile/settings/widgets.py index d84a7fe4..75773652 100644 --- a/.config/qtile/settings/widgets.py +++ b/.config/qtile/settings/widgets.py @@ -1,6 +1,5 @@ from libqtile import widget from settings.wal import wal - spacer_len = 3 wal_color = wal["colors"] diff --git a/.config/qtile/xephyr.sh b/.config/qtile/xephyr.sh new file mode 100755 index 00000000..75c9ffba --- /dev/null +++ b/.config/qtile/xephyr.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +function cleanup { + echo "cleaning up!" + xeph_qtile=0 +} + +xeph_qtile=1 +Xephyr -br -ac -noreset -screen 800x600 :1 & +export DISPLAY=:1 +qtile start & + +trap cleanup EXIT diff --git a/.config/xmobar/mouse_battery b/.config/xmobar/mouse_battery index 373b49fe..57858da7 100755 --- a/.config/xmobar/mouse_battery +++ b/.config/xmobar/mouse_battery @@ -1,10 +1,18 @@ status=$(cat /sys/class/power_supply/hidpp_battery_*/uevent | grep POWER_SUPPLY_VOLTAGE) voltage=$(echo $status | cut -c26-29) -if [ "$voltage" -ge 3200 ]; then +if [ "$voltage" -ge 3700 ]; then color="#b8bb26" else color="#fb4934" fi -echo "${voltage}mV" +status1=$(cat /sys/class/power_supply/hidpp_battery_*/uevent | grep POWER_SUPPLY_STATUS | tail -n1) +charge=$(echo $status1 | cut -c21-) +if [ "$charge" = "Discharging" ]; then + color1="#fb4934" +else + color1="#b8bb26" +fi + +echo "${voltage}mV" diff --git a/.config/xmobar/volume b/.config/xmobar/volume index 488e20b2..1dc553e2 100755 --- a/.config/xmobar/volume +++ b/.config/xmobar/volume @@ -8,6 +8,4 @@ else color="#b8bb26" fi -mpcvolume=$(mpc volume) - -echo "${mpcvolume:7:10} - $volume" +echo " $volume" diff --git a/.config/xmobar/xmobarrc b/.config/xmobar/xmobarrc index 23f6857e..fc442ad8 100755 --- a/.config/xmobar/xmobarrc +++ b/.config/xmobar/xmobarrc @@ -1,9 +1,9 @@ Config { font = "xft:Mononoki Nerd Font:pixelsize=12:antialias=true:hinting=true" , bgColor = "#282828" , fgColor = "#ebdbb2" - , position = Static {xpos = 0, ypos = 0, width = 2560, height = 20} + , position = Static {xpos = 2560, ypos = 0, width = 2560, height = 20} , iconRoot = "X" - , allDesktops = False + , allDesktops = True , commands = [ Run Cpu ["-t", " %","-H", "2"] 10 , Run Memory ["-t", "%"] 10 , Run Network "enp4s0" [ "-t", "kb/kb" ] 10 @@ -15,5 +15,5 @@ Config { font = "xft:Mononoki Nerd Font:pixelsize=12:antialias=true:hinting=true ] , sepChar = "%" , alignSep = "}{" - , template = " %StdinReader%}%date%{%enp4s0% |  %mouse_battery% | %volume% | 閭%cpu% |  %memory% |%gamemode% " + , template = " %StdinReader%}%date%{%enp4s0% | %mouse_battery% | %volume% | 閭%cpu% |  %memory% |%gamemode% " } diff --git a/.xinitrc b/.xinitrc index 7f77025b..6a1da1bf 100644 --- a/.xinitrc +++ b/.xinitrc @@ -1 +1,3 @@ +[ -f "/home/tstarr/.ghcup/env" ] && source "/home/tstarr/.ghcup/env" exec dbus-launch xmonad +#exec qtile start diff --git a/.xmonad/xmonad.hs b/.xmonad/xmonad.hs index 05cb5761..27146119 100644 --- a/.xmonad/xmonad.hs +++ b/.xmonad/xmonad.hs @@ -1,265 +1,244 @@ -- Base -import XMonad -import Data.Monoid +import XMonad hiding (Tall(..)) import System.Exit -import System.IO +import System.IO import qualified XMonad.StackSet as W -import qualified Data.Map as M import System.Directory (getHomeDirectory) - +import Data.Semigroup -- Hooks import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageHelpers import XMonad.Hooks.WorkspaceHistory import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..)) - +import XMonad.Hooks.DynamicProperty -- Layouts import XMonad.Layout.NoBorders -import XMonad.Layout.Gaps import XMonad.Layout.Spacing -import XMonad.Layout.ThreeColumns import XMonad.Layout.Tabbed -import XMonad.Layout.Renamed -import XMonad.Layout.LayoutModifier -import XMonad.Layout.Combo -import XMonad.Layout.TwoPane import XMonad.Layout.WindowNavigation - --- Utilities -import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe) +import XMonad.Layout.SimpleFloat +import XMonad.Layout.HintedTile +--Utilities +import XMonad.Util.Run (spawnPipe) import XMonad.Util.SpawnOnce -import XMonad.Util.NamedScratchpad import XMonad.Util.EZConfig (additionalKeysP, removeKeys) -import XMonad.Util.NamedActions import XMonad.Util.NamedScratchpad -import XMonad.Util.NamedWindows (getName) - -- Actions -import XMonad.Actions.CycleWS (moveTo, shiftTo, WSType(..), nextScreen, prevScreen) -import XMonad.Actions.DynamicProjects -import XMonad.Actions.DynamicWorkspaces -import XMonad.Actions.CopyWindow -import XMonad.Actions.Commands - +import XMonad.Actions.DynamicProjects (Project (..), dynamicProjects, switchProjectPrompt, shiftToProjectPrompt, switchProject, shiftToProject) +import XMonad.Actions.UpdatePointer +import XMonad.Actions.Navigation2D -- Prompt import XMonad.Prompt --- Data -import Data.Maybe (isJust) - -- Terminal to use -myTerminal = "alacritty" - +myTerminal :: String +myTerminal = "alacritty" -- Focus follows mouse pointer myFocusFollowsMouse :: Bool myFocusFollowsMouse = True - -- Define mod keys +myModMask :: KeyMask myModMask = mod4Mask -altMask = mod1Mask - -- Define volume keys and commands lowerVolumeCmd = "pulseaudio-ctl down 2" raiseVolumeCmd = "pulseaudio-ctl up 2" muteVolumeCmd = "pulseaudio-ctl mute" - -- Count windows windowCount :: X (Maybe String) windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset - -- Define workspaces -myWorkspaces = ["1","2","3","4","5","6","7","8","9"] - +myWorkspaces = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] -- Width of window border -myBorderWidth = 2 - +myBorderWidth = 2 -- Border colors myNormalBorderColor = "#ebdbb2" myFocusedBorderColor = "#d3869b" - --- Prompt theming -myFont = "xft:Mononoki Nerd Font:bold:size=9:antialias=true:hinting=true" -yellow = "#504945" -base03 = "#ebdbb2" -active = "#b8bb26" -prompt = 20 - -myPromptTheme = def - { font = myFont - , bgColor = base03 - , fgColor = active - , fgHLight = base03 - , bgHLight = active - , borderColor = base03 - , promptBorderWidth = 0 - , height = prompt - , position = Top +-- Configuration for myNav2D +myNav2DConf = def + { defaultTiledNavigation = centerNavigation + , floatNavigation = centerNavigation + , screenNavigation = lineNavigation + , layoutNavigation = [("Spacing Full", centerNavigation)] + , unmappedWindowRect = [("Spacing Full", singleWindowRect)] } - + myStartupHook = do spawnOnce "nitrogen --restore &" spawnOnce "lxsession &" spawnOnce "xsetroot -cursor_name left_ptr" + spawnOnce "xmodmap ~/.config/xmodmap/Xmodmap" spawnOnce "imwheel -b 45 &" spawnOnce "play-with-mpv &" - -------------------------------------------------------------------------}}} --- Layouts {{{ --- --- Alot stolen from https://github.com/altercation/dotfiles-tilingwm ---------------------------------------------------------------------------- + spawnOnce "udiskie &" + spawnOnce "dunst -conf ~/.config/dunst/dunstrc" -myLayout = windowNavigation $ spacing 2 $ smartBorders (tiled ||| Mirror tiled ||| Full ||| ThreeColMid 1 (3/100) (1/2) ||| tabTwoPane) +projects :: [Project] +projects = + [ Project { projectName = "dev" + , projectDirectory = "~/devel" + , projectStartHook = Just $ do spawn "emacs" + spawn myTerminal + }, + Project { projectName = "game" + , projectDirectory = "~/" + , projectStartHook = Nothing + } + ] + +myLayout = windowNavigation $ spacing 2 $ smartBorders (tiled Tall ||| tiled Wide ||| Full ||| simpleFloat) where -- default tiling algorithm partitions the screen into two panes - tiled = Tall nmaster delta ratio + --tiled = Tall nmaster delta ratio + tiled = HintedTile 1 0.03 0.5 TopLeft -- The default number of windows in the master pane - nmaster = 1 + --nmaster = 1 -- Default proportion of screen occupied by master pane - ratio = 1/2 + --ratio = 1/2 -- Percent of screen to increment by when resizing panes - delta = 2/100 - - tabTwoPane = renamed [Replace "TwoPane Tabs"] $ combineTwo (TwoPane 0.03 0.5) (tabs) (tabs) - - tabs = tabbed shrinkText myTabTheme - -myTabTheme = def { fontName = myFont - , activeColor = "#46d9ff" - , inactiveColor = "#313846" - , activeBorderColor = "#46d9ff" - , inactiveBorderColor = "#282c34" - , activeTextColor = "#282c34" - , inactiveTextColor = "#d0d0d0" - } + --delta = 2/100 myScratchPads :: [NamedScratchpad] myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm - , NS "scr-mpv" spawnMpv findMpv manageMpv - , NS "discord" spawnDiscord findDiscord manageDiscord ] + , NS "discord" spawnDiscord findDiscord manageDiscord + , NS "keepassxc" spawnKeepass findKeepass manageKeepass + , NS "gsimplecal" spawnCal findCal manageCal + , NS "scratch-emacs" spawnEmacs findEmacs manageEmacs ] where - spawnTerm = myTerminal ++ " -t terminal" + spawnTerm = myTerminal ++ " -t terminal" findTerm = title =? "terminal" manageTerm = customFloating $ W.RationalRect l t w h where h = 0.9 w = 0.9 - t = 0.95 -h - l = 0.95 -w - - spawnMpv = "mpv --player-operation-mode=pseudo-gui --title=scr-mpv" - findMpv = title =? "scr-mpv" - manageMpv = customFloating $ W.RationalRect l t w h - where - h = 0.9 - w = 0.9 - t = 0.95 -h + t = 0.95 -h l = 0.95 -w spawnDiscord = "discord" - findDiscord = appName =? "discord" + findDiscord = appName =? "discord" manageDiscord = customFloating $ W.RationalRect l t w h where h = 0.9 w = 0.9 - t = 0.95 -h + t = 0.95 -h l = 0.95 -w + spawnKeepass = "keepassxc" + findKeepass = appName =? "keepassxc" + manageKeepass = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 -h + l = 0.95 -w + + spawnCal = "gsimplecal" + findCal = appName =? "gsimplecal" + manageCal = customFloating $ W.RationalRect l t w h + where + h = 0.125 + w = 0.1 + t = 0.15 -h + l = 0.55 -w + + spawnEmacs = "emacs --eval '(set-frame-name \"scratch-emacs\")'" + findEmacs = title =? "scratch-emacs" + manageEmacs = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 -h + l = 0.95 -w + +-- Set default display modes for applications myManageHook = composeAll -- Float fullscreen apps (mostly games) [isDialog --> doCenterFloat, isFullscreen --> doFullFloat, - className =? "Gimp" --> doFullFloat, - className =? "Anki" --> doFullFloat, - className =? "mpv" --> doRectFloat (W.RationalRect 0.55 0.05 0.4 0.4), - className =? "Steam" --> doFullFloat, - className =? "microsoft teams - preview" --> doFullFloat, + className =? "Gimp" --> doFullFloat, + className =? "mpv" --> doRectFloat (W.RationalRect 0.55 0.05 0.4 0.4), + className =? "Steam" --> doFullFloat, namedScratchpadManageHook myScratchPads] - -myEventHook = mempty - -myLogHook = return () +-- Set dynamic display modes +myEventHook :: Event -> X All +myEventHook = dynamicPropertyChange "WM_NAME" (title =? "scratch-emacs" --> floating) + where floating = customFloating $ W.RationalRect (1/6) 0.05 (2/3) 0.9 +-- Log hook +myLogHook = updatePointer (0.5, 0.5) (0, 0) myKeys :: String -> [([Char], X ())] -myKeys home = +myKeys home = [ - -------------------------------------------------- - -- Window/Focus Manipulation - -------------------------------------------------- + -------------------------------------------------- + -- Window/Focus Manipulation + -------------------------------------------------- -- Rotate through the available layout algorithms ("M-", sendMessage NextLayout) - -- Move focus to the next window - , ("M-j", windows W.focusDown) - -- Move focus to the previous window - , ("M-k", windows W.focusUp) - -- Switch focus to next monitor - , ("M-.", nextScreen) - -- Switch focus to prev monitor - , ("M-,", prevScreen) - -- Swap the focused window with the next window/tabs - , ("M-S-j", sequence_ [windows W.swapDown, sendMessage $ Move R]) - -- Swap the focused window with the previous window/tabs - , ("M-S-k", sequence_ [windows W.swapUp, sendMessage $ Move L]) - -- Move focus to the master window - , ("M-m", windows W.focusMaster) - -- Swap the focused window and the master window - , ("M-c", windows W.swapMaster) -- Shrink the master area - , ("M-h", sendMessage Shrink) + , ("M-C-h", sendMessage Shrink) -- Expand the master area - , ("M-l", sendMessage Expand) - -- Copy window to all workspaces - , ("M-x c", toggleCopyToAll) + , ("M-C-l", sendMessage Expand) -- Push window back into tiling , ("M-t", withFocused $ windows . W.sink) -- close focused window , ("M-q", kill) - -------------------------------------------------- - -- Basic Utils - -------------------------------------------------- - -- Spawn terminal - , ("M-" , spawn "alacritty") - -- Spawn rofi drun - , ("M-w" , spawn "rofi -show drun") - -- Spawn rofi window - , ("M-S-w", spawn "rofi -show window") - - -------------------------------------------------- - -- Scratchpads - -------------------------------------------------- - -- Spawn rofi window - , ("M-S-", namedScratchpadAction myScratchPads "terminal") - -- Spawn rofi window - , ("M-d", namedScratchpadAction myScratchPads "discord") - -- Spawn rofi window - , ("M-v", namedScratchpadAction myScratchPads "scr-mpv") + -------------------------------------------------- + -- Basic Utils + -------------------------------------------------- + -- Spawn terminal - -------------------------------------------------- - -- Open Applications - -------------------------------------------------- - -- Spawn firefox + , ("M-" , spawn "alacritty") + -- Spawn rofi drun + , ("M-w" , spawn "rofi -show run -theme gruvbox-dark-soft") + + -------------------------------------------------- + -- Scratchpads + -------------------------------------------------- + + -- Spawn terminal scratchpad + , ("M-S-", namedScratchpadAction myScratchPads "terminal") + -- Spawn discord scratchpad + , ("M-d", namedScratchpadAction myScratchPads "discord") + -- Spawn keepass scratchpad + , ("M-m", namedScratchpadAction myScratchPads "keepassxc") + -- Spawn calendar scratchpad + , ("M-c", namedScratchpadAction myScratchPads "gsimplecal") + -- Spawn emacs scratchpad + , ("M-e", namedScratchpadAction myScratchPads "scratch-emacs") + + -------------------------------------------------- + -- Dynamic Projects + -------------------------------------------------- + , ("M-p d", switchProject (projects !! 0)) + , ("M-p S-d", shiftToProject (projects !! 0)) + , ("M-p g", switchProject (projects !! 1)) + , ("M-p S-g", shiftToProject (projects !! 1)) + + -------------------------------------------------- + -- Open Applications + -------------------------------------------------- + -- Spawn firefox , ("M-o b" , spawn "brave") - -- Spawn lutris + -- Spawn lutris , ("M-o l" , spawn "lutris") - -- Spawn steam + -- Spawn steam , ("M-o s" , spawn "steam") - -- Spawn flameshot + -- Spawn flameshot , ("M-o c" , spawn "flameshot gui") - -- Spawn emacs + -- Spawn emacs , ("M-o e" , spawn "emacs") - -------------------------------------------------- + -------------------------------------------------- -- System Utils - -------------------------------------------------- + -------------------------------------------------- -- Recompile and restart xmonad , ("M-x r", spawn "xmonad --recompile; xmonad --restart") -- Quit xmonad , ("M-x q", io (exitWith ExitSuccess)) -- Start gamemode , ("M-x g", spawn "gamemoded -r") - -- Stop gamemode + -- Stop gamemode , ("M-x S-g", spawn "killall gamemoded") -- mute overall volume , ("", spawn muteVolumeCmd) @@ -268,25 +247,34 @@ myKeys home = -- lower overall volume , ("", spawn lowerVolumeCmd) ] - where - toggleCopyToAll = wsContainingCopies >>= \ws -> case ws of - [] -> windows copyToAll - _ -> killAllOtherCopies - +-- Remove the default binding for quit xmonad rmKeys :: String -> [(KeyMask, KeySym)] -rmKeys keys = +rmKeys keys = [ - -- Remove the default quit xmonad bind (myModMask .|. shiftMask, xK_q) ] -main = do +main = do home <- getHomeDirectory xmproc0 <- spawnPipe "xmobar -x 0 ~/.config/xmobar/xmobarrc" - -- - xmonad $ docks $ ewmh $ ewmhFullscreen def + -- + xmonad + $ dynamicProjects projects + $ docks + $ ewmhFullscreen + $ withNavigation2DConfig myNav2DConf + $ navigation2DP def + ("k", "h", "j", "l") + [("M-", windowGo), + ("M-S-", windowSwap)] + False + $ additionalNav2DKeysP ("", ",", "", ".") + [("M-", screenGo), + ("M-S-", screenSwap)] + False + $ def { - -- Simple items + -- Simple items terminal = myTerminal, focusFollowsMouse = myFocusFollowsMouse, borderWidth = myBorderWidth, @@ -300,16 +288,16 @@ main = do manageHook = myManageHook, handleEventHook = myEventHook, logHook = workspaceHistoryHook <+> myLogHook <+> dynamicLogWithPP xmobarPP - { ppOutput = \x -> hPutStrLn xmproc0 x - , ppCurrent = xmobarColor "#b8bb26" "" . wrap "[" "]" -- Current workspace in xmobar - , ppVisible = xmobarColor "#83a598" "" -- Visible but not current workspace - , ppHidden = xmobarColor "#83a598" "" . wrap "*" "" -- Hidden workspaces in xmobar - , ppHiddenNoWindows= \( _ ) -> "" -- Only shows visible workspaces. Useful for TreeSelect. - , ppTitle = xmobarColor "#ebdbb2" "" . shorten 60 -- Title of active window in xmobar - , ppSep = " | " -- Separators in xmobar - , ppUrgent = xmobarColor "#fb4934" "" . wrap "!" "!" -- Urgent workspace - , ppExtras = [windowCount] -- # of windows current workspace + { ppOutput = \x -> hPutStrLn xmproc0 x + , ppCurrent = xmobarColor "#b8bb26" "" . wrap "[" "]" -- Current workspace in xmobar + , ppVisible = xmobarColor "#83a598" "" -- Visible but not current workspace + , ppHidden = xmobarColor "#83a598" "" . wrap "*" "" -- Hidden workspaces in xmobar + , ppHiddenNoWindows= \( _ ) -> "" -- Only shows visible workspaces. Useful for TreeSelect. + , ppTitle = xmobarColor "#ebdbb2" "" . shorten 60 -- Title of active window in xmobar + , ppSep = " | " -- Separators in xmobar + , ppUrgent = xmobarColor "#fb4934" "" . wrap "!" "!" -- Urgent workspace + , ppExtras = [windowCount] -- # of windows current workspace , ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]}, - startupHook = myStartupHook + startupHook = myStartupHook } `removeKeys` rmKeys home `additionalKeysP` myKeys home diff --git a/.xmonad/xmonad.org b/.xmonad/xmonad.org new file mode 100644 index 00000000..3d1f0b3d --- /dev/null +++ b/.xmonad/xmonad.org @@ -0,0 +1,347 @@ +#+title: Xmomad - Personal Xmonad Config +#+author: Tyler Starr +#+email: tyler@tstarr.us +#+keywords: config xmonad haskell wm +* References +* Configuration +** Imports + +#+begin_src haskell :tangle "xmonad.hs" +-- Base +import XMonad hiding (Tall(..)) +import System.Exit +import System.IO +import qualified XMonad.StackSet as W +import System.Directory (getHomeDirectory) +import Data.Semigroup +-- Hooks +import XMonad.Hooks.EwmhDesktops +import XMonad.Hooks.ManageDocks +import XMonad.Hooks.ManageHelpers +import XMonad.Hooks.WorkspaceHistory +import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..)) +import XMonad.Hooks.DynamicProperty +-- Layouts +import XMonad.Layout.NoBorders +import XMonad.Layout.Spacing +import XMonad.Layout.Tabbed +import XMonad.Layout.WindowNavigation +import XMonad.Layout.SimpleFloat +import XMonad.Layout.HintedTile +--Utilities +import XMonad.Util.Run (spawnPipe) +import XMonad.Util.SpawnOnce +import XMonad.Util.EZConfig (additionalKeysP, removeKeys) +import XMonad.Util.NamedScratchpad +-- Actions +import XMonad.Actions.DynamicProjects (Project (..), dynamicProjects, switchProjectPrompt, shiftToProjectPrompt, switchProject, shiftToProject) +import XMonad.Actions.UpdatePointer +import XMonad.Actions.Navigation2D +-- Prompt +import XMonad.Prompt +#+end_src + +** Variables + +#+begin_src haskell :tangle "xmonad.hs" +-- Terminal to use +myTerminal :: String +myTerminal = "alacritty" +-- Focus follows mouse pointer +myFocusFollowsMouse :: Bool +myFocusFollowsMouse = True +-- Define mod keys +myModMask :: KeyMask +myModMask = mod4Mask +-- Define volume keys and commands +lowerVolumeCmd = "pulseaudio-ctl down 2" +raiseVolumeCmd = "pulseaudio-ctl up 2" +muteVolumeCmd = "pulseaudio-ctl mute" +-- Count windows +windowCount :: X (Maybe String) +windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset +-- Define workspaces +myWorkspaces = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] +-- Width of window border +myBorderWidth = 2 +-- Border colors +myNormalBorderColor = "#ebdbb2" +myFocusedBorderColor = "#d3869b" +-- Configuration for myNav2D +myNav2DConf = def + { defaultTiledNavigation = centerNavigation + , floatNavigation = centerNavigation + , screenNavigation = lineNavigation + , layoutNavigation = [("Spacing Full", centerNavigation)] + , unmappedWindowRect = [("Spacing Full", singleWindowRect)] + } +#+end_src + +** Startup + +#+begin_src haskell :tangle "xmonad.hs" +myStartupHook = do + spawnOnce "nitrogen --restore &" + spawnOnce "lxsession &" + spawnOnce "xsetroot -cursor_name left_ptr" + spawnOnce "xmodmap ~/.config/xmodmap/Xmodmap" + spawnOnce "imwheel -b 45 &" + spawnOnce "play-with-mpv &" + spawnOnce "udiskie &" + spawnOnce "dunst -conf ~/.config/dunst/dunstrc" +#+end_src + +** Projects + +#+begin_src haskell :tangle "xmonad.hs" +projects :: [Project] +projects = + [ Project { projectName = "dev" + , projectDirectory = "~/devel" + , projectStartHook = Just $ do spawn "emacs" + spawn myTerminal + }, + Project { projectName = "game" + , projectDirectory = "~/" + , projectStartHook = Nothing + } + ] +#+end_src + +** Layout + +#+begin_src haskell :tangle "xmonad.hs" +myLayout = windowNavigation $ spacing 2 $ smartBorders (tiled Tall ||| tiled Wide ||| Full ||| simpleFloat) + where + -- default tiling algorithm partitions the screen into two panes + --tiled = Tall nmaster delta ratio + tiled = HintedTile 1 0.03 0.5 TopLeft + -- The default number of windows in the master pane + --nmaster = 1 + -- Default proportion of screen occupied by master pane + --ratio = 1/2 + -- Percent of screen to increment by when resizing panes + --delta = 2/100 +#+end_src + +** Scratchpads + +#+begin_src haskell :tangle "xmonad.hs" +myScratchPads :: [NamedScratchpad] +myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm + , NS "discord" spawnDiscord findDiscord manageDiscord + , NS "keepassxc" spawnKeepass findKeepass manageKeepass + , NS "gsimplecal" spawnCal findCal manageCal + , NS "scratch-emacs" spawnEmacs findEmacs manageEmacs ] + where + spawnTerm = myTerminal ++ " -t terminal" + findTerm = title =? "terminal" + manageTerm = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 -h + l = 0.95 -w + + spawnDiscord = "discord" + findDiscord = appName =? "discord" + manageDiscord = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 -h + l = 0.95 -w + + spawnKeepass = "keepassxc" + findKeepass = appName =? "keepassxc" + manageKeepass = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 -h + l = 0.95 -w + + spawnCal = "gsimplecal" + findCal = appName =? "gsimplecal" + manageCal = customFloating $ W.RationalRect l t w h + where + h = 0.125 + w = 0.1 + t = 0.15 -h + l = 0.55 -w + + spawnEmacs = "emacs --eval '(set-frame-name \"scratch-emacs\")'" + findEmacs = title =? "scratch-emacs" + manageEmacs = customFloating $ W.RationalRect l t w h + where + h = 0.9 + w = 0.9 + t = 0.95 -h + l = 0.95 -w +#+end_src + +** Hooks + +#+begin_src haskell :tangle "xmonad.hs" +-- Set default display modes for applications +myManageHook = composeAll + -- Float fullscreen apps (mostly games) + [isDialog --> doCenterFloat, + isFullscreen --> doFullFloat, + className =? "Gimp" --> doFullFloat, + className =? "mpv" --> doRectFloat (W.RationalRect 0.55 0.05 0.4 0.4), + className =? "Steam" --> doFullFloat, + namedScratchpadManageHook myScratchPads] +-- Set dynamic display modes +myEventHook :: Event -> X All +myEventHook = dynamicPropertyChange "WM_NAME" (title =? "scratch-emacs" --> floating) + where floating = customFloating $ W.RationalRect (1/6) 0.05 (2/3) 0.9 +-- Log hook +myLogHook = updatePointer (0.5, 0.5) (0, 0) +#+end_src + +** Keybinds + +#+begin_src haskell :tangle "xmonad.hs" +myKeys :: String -> [([Char], X ())] +myKeys home = + [ + -------------------------------------------------- + -- Window/Focus Manipulation + -------------------------------------------------- + -- Rotate through the available layout algorithms + ("M-", sendMessage NextLayout) + -- Shrink the master area + , ("M-C-h", sendMessage Shrink) + -- Expand the master area + , ("M-C-l", sendMessage Expand) + -- Push window back into tiling + , ("M-t", withFocused $ windows . W.sink) + -- close focused window + , ("M-q", kill) + + -------------------------------------------------- + -- Basic Utils + -------------------------------------------------- + -- Spawn terminal + + , ("M-" , spawn "alacritty") + -- Spawn rofi drun + , ("M-w" , spawn "rofi -show run -theme gruvbox-dark-soft") + + -------------------------------------------------- + -- Scratchpads + -------------------------------------------------- + + -- Spawn terminal scratchpad + , ("M-S-", namedScratchpadAction myScratchPads "terminal") + -- Spawn discord scratchpad + , ("M-d", namedScratchpadAction myScratchPads "discord") + -- Spawn keepass scratchpad + , ("M-m", namedScratchpadAction myScratchPads "keepassxc") + -- Spawn calendar scratchpad + , ("M-c", namedScratchpadAction myScratchPads "gsimplecal") + -- Spawn emacs scratchpad + , ("M-e", namedScratchpadAction myScratchPads "scratch-emacs") + + -------------------------------------------------- + -- Dynamic Projects + -------------------------------------------------- + --, ("M-p s", switchProjectPrompt projectsTheme) + --, ("M-p S", shiftToProjectPrompt projectsTheme) + , ("M-p d", switchProject (projects !! 0)) + , ("M-p S-d", shiftToProject (projects !! 0)) + , ("M-p g", switchProject (projects !! 1)) + , ("M-p S-g", shiftToProject (projects !! 1)) + + -------------------------------------------------- + -- Open Applications + -------------------------------------------------- + -- Spawn firefox + , ("M-o b" , spawn "brave") + -- Spawn lutris + , ("M-o l" , spawn "lutris") + -- Spawn steam + , ("M-o s" , spawn "steam") + -- Spawn flameshot + , ("M-o c" , spawn "flameshot gui") + -- Spawn emacs + , ("M-o e" , spawn "emacs") + + -------------------------------------------------- + -- System Utils + -------------------------------------------------- + -- Recompile and restart xmonad + , ("M-x r", spawn "xmonad --recompile; xmonad --restart") + -- Quit xmonad + , ("M-x q", io (exitWith ExitSuccess)) + -- Start gamemode + , ("M-x g", spawn "gamemoded -r") + -- Stop gamemode + , ("M-x S-g", spawn "killall gamemoded") + -- mute overall volume + , ("", spawn muteVolumeCmd) + -- raise overall volume + , ("", spawn raiseVolumeCmd) + -- lower overall volume + , ("", spawn lowerVolumeCmd) + ] +-- Remove the default binding for quit xmonad +rmKeys :: String -> [(KeyMask, KeySym)] +rmKeys keys = + [ + (myModMask .|. shiftMask, xK_q) + ] +#+end_src + +** Main + +#+begin_src haskell :tangle "xmonad.hs" +main = do + home <- getHomeDirectory + xmproc0 <- spawnPipe "xmobar -x 0 ~/.config/xmobar/xmobarrc" + -- + xmonad + $ dynamicProjects projects + $ docks + $ ewmhFullscreen + $ withNavigation2DConfig myNav2DConf + $ navigation2DP def + ("k", "h", "j", "l") + [("M-", windowGo), + ("M-S-", windowSwap)] + False + $ additionalNav2DKeysP ("", ",", "", ".") + [("M-", screenGo), + ("M-S-", screenSwap)] + False + $ def + { + -- Simple items + terminal = myTerminal, + focusFollowsMouse = myFocusFollowsMouse, + borderWidth = myBorderWidth, + modMask = myModMask, + workspaces = myWorkspaces, + normalBorderColor = myNormalBorderColor, + focusedBorderColor = myFocusedBorderColor, + + -- Hooks, Layouts + layoutHook = avoidStruts $ myLayout, + manageHook = myManageHook, + handleEventHook = myEventHook, + logHook = workspaceHistoryHook <+> myLogHook <+> dynamicLogWithPP xmobarPP + { ppOutput = \x -> hPutStrLn xmproc0 x + , ppCurrent = xmobarColor "#b8bb26" "" . wrap "[" "]" -- Current workspace in xmobar + , ppVisible = xmobarColor "#83a598" "" -- Visible but not current workspace + , ppHidden = xmobarColor "#83a598" "" . wrap "*" "" -- Hidden workspaces in xmobar + , ppHiddenNoWindows= \( _ ) -> "" -- Only shows visible workspaces. Useful for TreeSelect. + , ppTitle = xmobarColor "#ebdbb2" "" . shorten 60 -- Title of active window in xmobar + , ppSep = " | " -- Separators in xmobar + , ppUrgent = xmobarColor "#fb4934" "" . wrap "!" "!" -- Urgent workspace + , ppExtras = [windowCount] -- # of windows current workspace + , ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]}, + startupHook = myStartupHook + } `removeKeys` rmKeys home + `additionalKeysP` myKeys home +#+end_src