import Control.Monad (when) import Data.Map qualified as M import Data.Monoid import Data.Ratio import Graphics.X11.ExtraTypes.XF86 import System.Exit import XMonad import XMonad.Actions.KeyRemap import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.ManageDocks import XMonad.Hooks.StatusBar import XMonad.Hooks.StatusBar.PP import XMonad.Layout.Circle import XMonad.Layout.DraggingVisualizer import XMonad.Layout.Grid import XMonad.Layout.IfMax import XMonad.Layout.Magnifier import XMonad.Layout.Spacing import XMonad.Layout.Tabbed import XMonad.Layout.ThreeColumns import XMonad.Layout.VoidBorders import XMonad.Layout.WindowSwitcherDecoration import XMonad.Prompt import XMonad.Prompt.Layout import XMonad.StackSet qualified as W import XMonad.Actions.NoBorders import XMonad.Util.EZConfig myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ [ ((modm, xK_Return), spawn $ XMonad.terminal conf), ((modm .|. shiftMask, xK_q), kill), -- -- Rotate through the available layout algorithms ((modm, xK_space), sendMessage NextLayout), -- rofiing ((modm, xK_d), spawn "rofi -show drun"), ((modm .|. shiftMask, xK_e), spawn "rofi -show desktopctl -modes desktopctl:desktopctl -show-icons"), ((modm, xK_m), spawn "menu-qalc -- -theme gruvbox-dark"), ((modm, xK_i), spawn "rofimoji --selector-args '-theme gruvbox-dark' -f alchemical_symbols anatolian_hieroglyphs emojis braille_patterns box_drawing chess_symbols emoticons geometric_shapes gothic greek_extended math mathematical_alphanumeric_symbols mathematical_operators miscellaneous_symbols miscellaneous_mathematical_symbols-a miscellaneous_mathematical_symbols-b miscellaneous_symbols_and_arrows miscellaneous_symbols_and_pictographs miscellaneous_technical modi modifier_tone_letters musical_symbols nerd_font number_forms shorthand_format_controls specials variation_selectors vertical_forms -a copy"), -- screenshotting -- TODO: Fix/rewrite window-screenshot ((modm, xK_w), spawn "window-screenshot.nu"), ((modm, xK_s), spawn "flameshot gui -c -p $HOME/Pictures/screenshots"), ((modm, xK_a), spawn "flameshot screen -c -p $HOME/Pictures/screenshots"), ((modm, xK_t), spawn "ocr-screenshot.sh"), ((modm .|. shiftMask, xK_t), spawn "DEVICE=\"MELF0410:00 1FD2:7007\"; if [ $(xinput list-props \"$DEVICE\" | awk '/^\\tDevice Enabled \\([0-9]+\\):\\t[01]/ {print $NF}') = \"1\" ]; then xinput disable \"$DEVICE\"; else xinput enable \"$DEVICE\"; fi"), -- Push window back into tiling ((modm .|. shiftMask, xK_space), withFocused $ windows . W.sink), -- Resize viewed windows to the correct size ((modm, xK_n), refresh), -- Move focus to the next window ((modm, xK_Tab), layoutPrompt def), -- Move focus ((modm, xK_j), windows W.focusDown), ((modm, xK_k), windows W.focusUp), -- Swap the focused window with the next window ((modm .|. shiftMask, xK_j), windows W.swapDown), ((modm .|. shiftMask, xK_k), windows W.swapUp), -- Shrink the master area ((modm, xK_h), sendMessage Shrink), ((modm, xK_l), sendMessage Expand), -- Increment the number of windows in the master area ((modm, xK_comma), sendMessage (IncMasterN 1)), ((modm, xK_period), sendMessage (IncMasterN (-1))), ((modm, xK_b), sendMessage ToggleStruts >> withFocused toggleBorder), -- volume keys -- TODO: other media keys ((0, xF86XK_AudioRaiseVolume), spawn "amixer -D pulse sset Master 10%+"), ((0, xF86XK_AudioLowerVolume), spawn "amixer -D pulse sset Master 10%-"), ((0, xF86XK_AudioMute), spawn "amixer -D pulse sset Master toggle") ] ++ [ ((m .|. modm, k), windows $ f i) | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9], (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)] ] -- TODO: figure out multi screen stuff, including xinerama -- 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 -> do focus w mouseMoveWindow w windows W.shiftMaster ), -- mod-button2, Raise the window to the top of the stack ( (modm, button3), \w -> do focus w mouseResizeWindow w windows W.shiftMaster ) ] tabCfg = def { activeColor = "#282828", inactiveColor = "#1d2021", urgentColor = "#9d0006", activeBorderColor = "#504945", inactiveBorderColor = "#3c3836", urgentBorderColor = "#cc241d", activeTextColor = "#ebdbb2", inactiveTextColor = "#bdae93", urgentTextColor = "#ebdbb2" } myLayout = setupSpacing $ avoidStruts $ autoChoose ||| tabbed shrinkText tabCfg where -- default tiling algorithm partitions the screen into two panes autoChoose = IfMax 2 tiled $ IfMax 3 tiled_mag $ IfMax 4 grid_mag threeCol setupSpacing = spacingRaw True (Border 0 0 0 0) True (Border 7 7 7 7) True grid_mag = magnifiercz 1.4 Grid tiled = Tall nmaster delta ratio tiled_mag = magnifiercz' 1.4 tiled threeCol = magnifiercz' 1.6 $ ThreeColMid nmaster delta ratio -- 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 = 3 / 100 myManageHook = composeAll [ className =? "MPlayer" --> doFloat, className =? "Gimp" --> doFloat, className =? "firefox" --> doShift "browser", className =? "Evolution" --> doShift "comms", className =? "Signal" --> doShift "comms", className =? "SchildiChat" --> doShift "comms", resource =? "desktop_window" --> doIgnore, resource =? "kdesktop" --> doIgnore ] myStartupHook = do spawn "pgrep oneko || oneko -tofocus -tora -position +-1+5 -fg palevioletred3 -bg pink -name 'Rose the desktop kitty'" spawn "pgrep volumeicon || volumeicon" spawn "pgrep nm-applet || nm-applet" spawn "pgrep mullvad-gui || mullvad-vpn" spawn "feh --bg-fill ~/Pictures/wallpaper.jpg" killStatusBar "xmobar" spawnStatusBar "xmobar" xmeowbar = statusBarProp "xmobar" $ pure xmobarPP polybar = statusBarProp "polybar" $ pure xmobarPP barSpawner 0 = pure $ xmeowbar <> polybar barSpawner _ = mempty main :: IO() main = xmonad $ docks $ dynamicSBs barSpawner $ ewmh defaults defaults = def { -- simple stuff terminal = "kitty", focusFollowsMouse = False, clickJustFocuses = False, borderWidth = 2, modMask = mod4Mask, workspaces = ["comms", "browser"] ++ map show [3 .. 9], normalBorderColor = "#3c3836", focusedBorderColor = "#504945", keys = myKeys, mouseBindings = myMouseBindings, layoutHook =myLayout, manageHook = myManageHook, startupHook = myStartupHook }