New paste Repaste Download
-- System
import System.IO
import XMonad
import Control.Monad
-- Actions
import XMonad.Actions.CycleRecentWS
import XMonad.Actions.CycleWS
import XMonad.Actions.DwmPromote
import XMonad.Actions.DynamicWorkspaces
import XMonad.Actions.FloatKeys
import XMonad.Actions.FloatSnap
import XMonad.Actions.GridSelect
import XMonad.Actions.PhysicalScreens
import XMonad.Actions.UpdateFocus
import XMonad.Actions.WindowMenu
-- Config
import XMonad.Config.Desktop
import XMonad.Config.Kde
-- Hooks
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.FadeInactive
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.RefocusLast
import XMonad.Hooks.ScreenCorners
import XMonad.Hooks.StatusBar
import XMonad.Hooks.StatusBar.PP
-- Layout
import XMonad.Layout
import XMonad.Layout.Accordion
import XMonad.Layout.BinarySpacePartition
import XMonad.Layout.Column
import XMonad.Layout.Dishes
import XMonad.Layout.DragPane
import XMonad.Layout.Grid
import XMonad.Layout.IM
import XMonad.Layout.IndependentScreens
import XMonad.Layout.LayoutCombinators hiding ((|||))
import XMonad.Layout.LayoutModifier
import XMonad.Layout.NoBorders ( noBorders, smartBorders )
import XMonad.Layout.PerWorkspace
import XMonad.Layout.ResizableTile
import XMonad.Layout.SimpleFloat
import XMonad.Layout.SimplestFloat
import XMonad.Layout.Spacing
import XMonad.Layout.Spiral
import XMonad.Layout.StackTile
import XMonad.Layout.Tabbed
import XMonad.Layout.ThreeColumns
import XMonad.Layout.TwoPane
import XMonad.Layout.WindowNavigation
-- Prompt
import XMonad.Prompt
import XMonad.Prompt.Window
import XMonad.Prompt.Workspace
import XMonad.Prompt.FuzzyMatch
import XMonad.Prompt.RunOrRaise
-- Util
import XMonad.Util.ClickableWorkspaces
import XMonad.Util.Dmenu
import XMonad.Util.EZConfig
import XMonad.Util.NamedScratchpad
import XMonad.Util.NamedWindows (getName)
import XMonad.Util.NoTaskbar
import XMonad.Util.Paste
import XMonad.Util.Run
import XMonad.Util.Run(spawnPipe)
import XMonad.Util.Themes
-- Data
import Data.Functor
import Data.List (isInfixOf)
import Data.Maybe (fromMaybe)
import Data.Monoid
import Data.Ratio ((%))
import Data.Semigroup
import Text.Regex.Posix
import qualified Data.Map    as M
import qualified XMonad.Actions.ConstrainedResize as Sqr
import qualified XMonad.StackSet as W
-- Define a function to match the window name using regular expressions and extract relevant parts
matchesPattern :: String -> Maybe String
matchesPattern s = case s =~ "Windows 10 P2V Original Clone [^ ]+ - Oracle VM VirtualBox : ([0-9]+)" of
                     [[_, num]] -> Just num
                     _ -> Nothing
-- Manage Hook
myManageHook :: ManageHook
myManageHook = composeAll
  [
    -- Start doShift
    className `oneOf` [
        "Google-chrome",
        "claws-mail",
        "ktorrent"
    ] --> (doF . W.view <> doShift) "1:net",
    className `oneOf` [
        "URxvt"
    ] --> (doF . W.view <> doShift) "2:$>_",
    className `oneOf` [
        "VirtualBox Manager"
    ] --> (doF . W.view <> doShift) "5:vm",
    className `oneOf` [
        "Gimp-2.10",
        "okular",
        "Inkscape",
        "gwenview-NOT"
    ] --> (doF . W.view <> doShift) "6:gfx", -- Remove NOT to make it function again
    className `oneOf` [
        "mpv",
        "vlc",
        "smplayer",
        "obs"
    ] --> (doF . W.view <> doShift) "7:media",
    -- Sort Virtual Machines into separate workspaces
    className =? "VirtualBox Machine" <&&> title ^? "Windows 10 P2V Original Clone " <&&> title $? " Oracle VM VirtualBox : 1"
        --> (doF . W.view <> doShift) "8:win-A",
    className =? "VirtualBox Machine" <&&> title ^? "Windows 10 P2V Original Clone " <&&> title $? " Oracle VM VirtualBox : 2"
        --> (doF . W.view <> doShift) "8:win-B",
    name `oneOf` [
        "TAILS [Running] - Oracle VM VirtualBox",
        "Ubuntu BTRFS TEST [Running] - Oracle VM VirtualBox"
    ] --> (doF . W.view <> doShift) "9:linux",
    className `oneOf` [
        "libreoffice"
    ] --> (doF . W.view <> doShift) "10:office",
    className `oneOf` [
        "libreoffice",
        "plasma-discover",
        "krdc",
        "systemsettings",
        "Timeshift-gtk",
        "GParted",
        "plasma-systemmonitor",
        "muon",
        "partitionmanager",
        "Gsmartcontrol"
    ] --> (doF . W.view <> doShift) "11:sys",
    className `oneOf` [
        "discord",
        "firefox",
        "KeePassXC"
    ] --> (doF . W.view <> doShift) "12a:misc 1",
    className `oneOf` [
        -- "Emacs"
    ] --> (doF . W.view <> doShift) "3:emacs",
    -- End doShift
    -- Start doFloat
    role `oneOf` [
        "gimp-toolbox-color-dialog"
    ] --> doFloat,
    className `oneOf` [
        "plasmashell",
        "kmix",
        "krunner",
        "ksplashqml",
        "ksplashsimple",
        "ksplashx",
        "Plasma",
        "Plasma-desktop",
        "kcmshell5"
    ] --> doFloat,
    -- End doFloat
    resource `oneOf` [
        "desktop_window",
        "kdesktop"
    ] --> doIgnore,
    name `oneOf` [
        "Diablo II",
        "Diablo II: Resurrected"
    ] --> (ask >>= doF . W.sink),
    name `oneOf` [  "Diablo II: Resurrected", "Diablo II" ] -->
      ask >>= \w -> liftX (screenWorkspace 1 >>= \x -> case x of
                              Just ws -> pure . Endo $ W.shiftWin "18:Diablo" w . W.view "18:Diablo" . W.view ws
                              Nothing -> pure . Endo $ W.view "18:Diablo" . W.shiftWin "18:Diablo" w),
    className `oneOf` [
        "steam_app_22330"
    ] -->  ask >>= \w -> liftX (screenWorkspace 1 >>= \x -> case x of
                              Just ws -> pure . Endo $ W.shiftWin "19:" w . W.view "19:" . W.view ws
                              Nothing -> pure . Endo $ W.view "19:" . W.shiftWin "19:" w)
--     name `oneOf` [  "Diablo II: Resurrected", "Diablo II" ] --> do
--       mtag <- liftX (screenWorkspace 1)
--       let doView = doF . W.view
--       (doView <> doShift) "18:Diablo" <> foldMap doView mtag
  ]
  where role = stringProperty "WM_WINDOW_ROLE"
        name = stringProperty "WM_NAME"
        prop `oneOf` ss = prop <&> (`elem` ss)
-- Workspaces
myWorkspaces =
  [
          "1:net"
        , "2:$>_"
        , "3:emacs"
        , "4:fm"
        , "5:vm"
        , "6:gfx"
        , "7:media"
        , "8:win-A"
        , "8:win-B"
        , "9:linux"
        , "10:office"
        , "11:sys"
        , "12a:misc 1"
        , "12b:misc 2"
        , "12c:misc 3"
        , "12d:misc 4"
        , "13:school"
        , "14:art"
        , "15:net"
        , "16:firefox"
        , "17:downloads"
        , "18:Diablo"
        , "19:"
        , "20:"
  ]
  -- Update mouse keybindings with conditional checks
myMouseBindings :: XConfig Layout -> M.Map (ButtonMask, Button) (Window -> X ())
myMouseBindings XConfig {XMonad.modMask = modMask} = M.fromList $
    -- Regular mouse bindings
    [ ((modMask, button1), \w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicMove (Just 50) (Just 50) w))
    , ((modMask .|. shiftMask, button1), \w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicResize [L,R,U,D] (Just 50) (Just 50) w))
    , ((modMask, button3), \w -> focus w >> mouseResizeWindow w >> afterDrag (snapMagicResize [R,D] (Just 50) (Just 50) w))
    ] ++
    -- Conditional mouse bindings based on active window
    [ ((modMask, button1), \w -> whenX (not <$> isActiveVMWindow w) $ focus w >> mouseMoveWindow w >> afterDrag (snapMagicMove (Just 50) (Just 50) w))
    , ((modMask .|. shiftMask, button1), \w -> whenX (not <$> isActiveVMWindow w) $ focus w >> mouseMoveWindow w >> afterDrag (snapMagicResize [L,R,U,D] (Just 50) (Just 50) w))
    , ((modMask, button3), \w -> whenX (not <$> isActiveVMWindow w) $ focus w >> mouseResizeWindow w >> afterDrag (snapMagicResize [R,D] (Just 50) (Just 50) w))
    ]
    where
        -- Function to check if the active window is a VirtualBox VM window
        isActiveVMWindow :: Window -> X Bool
        isActiveVMWindow = runQuery (className =? "VirtualBox Machine")
-- Layouts
mylayoutHook    =
    avoidStruts . smartBorders
        $ windowNavigation
        $ screenCornerLayoutHook
        $ onWorkspace "6:Gimp" (Full)
        -- $ onWorkspace "2:$>_" ( Full ||| Mirror (ResizableTall 1 (3/100) (1/2) []))
        $
        -- First layout Full Windows Tabbed Bottom
        -- tabbedBottomAlways shrinkText (theme darkTheme)
        windowNavigation Full
        ||| Mirror (Column 1)
        -- To Do: Configure BSP algorithm keybindings
        -- ||| emptyBSP
        ||| Accordion
        ||| Mirror Accordion
        ||| Grid
        ||| Mirror (Grid)
        ||| ResizableTall 1 (3/100) (1/2) []
        ||| Mirror (ResizableTall 1 (3/100) (1/2) [])
        ||| tiled
        ||| Mirror tiled
        ||| Dishes 2 (1/6)
        ||| spiral (6/7)
        ||| StackTile 1 (3/100) (1/2)
        ||| ThreeCol 1 (3/100) (1/2)
        ||| ThreeColMid 1 (3/100) (1/2)
        ||| TwoPane (3/100) (1/2)
        ||| simpleTabbedBottom
        ||| simpleTabbedLeft
        ||| simpleTabbedRight
        -- ||| withIM (1%7) (ClassName "kopete") Grid
        ||| simplestFloat
        -- ||| withIM (1%7) (ClassName "Tkabber") Grid
    where
    -- default tiling algorithm partitions the screen into two panes
    tiled   = Tall nmaster delta ratio
    nmaster = 1       -- The default number of windows in the master pane
    ratio   = 1/2     -- Default proportion of screen occupied by master pane
    delta   = 3/100   -- Percent of screen to increment by when resizing panes
    gimpLayout = simpleTabbed */* Mirror (Tall (1) (2/3) (3/100))
-- scratchpads
scratchpads :: [NamedScratchpad]
scratchpads = -- name, cmd, query, hook
              -- (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
              -- (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  [
    NS "konsole"
       "konsole"
       (className =? "konsole")
       (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  , NS "kate"
       "kate"
       (className =? "kate")
       (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  , NS "chromium"
       "chromium"
       (className =? "Chromium")
       (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  , NS "htop"
       "xst -e htop"
       (name =? "htop")
       (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  , NS "pavucontrol"
       "pavucontrol-qt"
       (className =? "pavucontrol-qt")
       (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  , NS "cool-retro-term"
       "cool-retro-term"
       (className =? "cool-retro-term")
       (noTaskbar <> customFloating (W.RationalRect (1/10) (1/10) (8/10) (8/10)))
  ]
  where name = stringProperty "WM_NAME"
-- Startup Hooks
myStartupHook = do
   -- Screen corners
   addScreenCorners [
        (SCUpperLeft, namedScratchpadAction scratchpads "konsole")
      , (SCLowerLeft, namedScratchpadAction scratchpads "kate")
      , (SCUpperRight, namedScratchpadAction scratchpads "konsole")
      , (SCLowerRight, namedScratchpadAction scratchpads "kate")
    ]
   adjustEventInput
myXPConfig = def { searchPredicate = fuzzyMatch
                 , sorter          = fuzzySort
                 }
-- toggleOrView ignoring scratchpad and named scratchpad workspace
toggleOrViewNoSP = toggleOrDoSkip ["NSP"] W.greedyView
-- Log Hooks
-- myLogHook :: X ()
-- myLogHook =
myXmobarLogHook xmproc = dynamicLogWithPP <=< clickablePP . filterOutWsPP [scratchpadWorkspaceTag] $ xmobarPP
    {
          ppOutput = hPutStrLn xmproc
        , ppTitle  = xmobarColor "white" "" . shorten 256
        , ppCurrent = xmobarColor "lightblue" "" . wrap "[" "]"
        , ppVisible = wrap "(" ")"
    }
-- Main Xmonad Function
main :: IO ()
main = do
    -- xmproc <- spawnPipe ("/home/stoned/.local/bin/xmobar ~/.xmobar/xmobarrc")
    xmproc <- spawnPipe ("~/.local/bin/xmobar ~/.xmobar/xmobarrc")
    xmonad $ docks $ ewmhFullscreen . ewmh $ def
        {
        -- hooks
          manageHook = manageDocks <+> myManageHook <+> namedScratchpadManageHook scratchpads <+> manageHook def
        , startupHook = myStartupHook
        , handleEventHook = focusOnMouseMove <+> screenCornerEventHook
        , layoutHook = mylayoutHook
        , logHook = myXmobarLogHook xmproc
        -- workspaces
        , workspaces = myWorkspaces
        -- current modifier key
        , modMask = mod4Mask
        -- Fix Virtual Box Winkey+Mouse
        , mouseBindings = myMouseBindings
        -- xmond config
        , focusedBorderColor = "black"
        , normalBorderColor = "#4A148C"
        , borderWidth = 1
        , focusFollowsMouse = True
        -- default terminal
        , terminal = "x-terminal-emulator"
        }
        `additionalMouseBindings`
        (
--        [
--        -- FloatSnap
--         ((mod4Mask, button1),
--            (\w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicMove (Just 50) (Just 50) w)))
--       , ((mod4Mask .|. shiftMask, button1),
--            (\w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicResize [L,R,U,D] (Just 50) (Just 50) w)))
--       , ((mod4Mask, button3),
--            (\w -> focus w >> mouseResizeWindow w >> afterDrag (snapMagicResize [R,D] (Just 50) (Just 50) w)))
--       ]
--          ++
        [
        -- Switch windows using mousewheel
          ((mod4Mask .|. shiftMask, button4), (\w -> windows W.focusUp))
        , ((mod4Mask .|. shiftMask, button5), (\w -> windows W.focusDown))
        -- Resize master pane using mousewheel
        , ((mod4Mask, button5), (\w -> sendMessage Expand))
        , ((mod4Mask, button4), (\w -> sendMessage Shrink))
        ]
        )
        `additionalKeys`
        ([
              ((m .|. mod4Mask, key), windows $ f i)
            | (i, key) <- zip (myWorkspaces) ([xK_1 .. xK_9] ++ [xK_0, xK_minus, xK_equal])
            , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]
        ] ++
        [
              ((m .|. mod4Mask, key), screenWorkspace sc >>= flip whenJust (windows . f))
            | (key, sc) <- zip [xK_F1..xK_F2] [0..]
            , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]
        ]
        )
        `additionalKeysP`
        -- Key modifier info:
        -- shift       Shift_L (0x32),  Shift_R (0x3e)
        -- control     Control_L (0x25),  Control_R (0x69)
        -- mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
        -- mod3        Hyper_R (0x42),  Hyper_L (0xcf)
        -- mod4        Super_L (0x85),  Super_R (0x86)
        -- M = Super (mod4)
        -- M1 = Alt
        -- M3 = Hyper (Caps Lock)
        [
            ("M-S-r", renameWorkspace def)          -- Winkey+Shift+r: Rename current workspace
            -- Window order / stack
            , ("M-S-j", windows W.swapDown)           -- Winkey+Shift+j: Swap focused window with next window ⚠ Conflict: defined again below
            , ("M-S-j", windows W.swapUp)             -- Winkey+Shift+j: Swap focused window with previous window ⚠ Overrides previous line
            -- Status bar & window menu
            , ("M-b", sendMessage ToggleStruts)       -- Winkey+b: Toggle status bar visibility
            , ("M-o", windowMenu)                     -- Winkey+o: Open window menu/options
            -- Master pane
            , ("M-<Return>", dwmpromote)             -- Winkey+Enter: Promote focused window to master pane
            -- Run / Raise prompts
            , ("M-C-x", runOrRaisePrompt def)         -- Winkey+Ctrl+x: Run or raise a program
            , ("M-<Escape>", runOrRaisePrompt def)    -- Winkey+Escape: Alternate run/raise prompt
            -- Window list selection
            , ("M-x w", goToSelected def)             -- Winkey+x then w: Show window list for selection
            -- GridSelect launcher
            , ("M-s", spawnSelected def [
                "discord"
                , "dolphin"
                , "firefox"
                , "gimp"
                , "google-chrome"
                , "kate"
                , "smplayer"
                , "systemsettings5"
                , "urxvt"
                , "konsole"
                , "xterm"
                , "sudo timeshift-gtk"
            ])                                      -- Winkey+s: GridSelect menu to launch apps
            -- Volume control (numpad)
            , ("<KP_Add>", spawn "~/bin/volume.sh plus")      -- Numpad + : Increase volume
            , ("<KP_Subtract>", spawn "~/bin/volume.sh minus")-- Numpad - : Decrease volume
            , ("<KP_Divide>", spawn "amixer -D pulse set Master 1+ toggle") -- Numpad / : Mute/unmute
            -- Terminal
            , ("M-S-t", spawn "x-terminal-emulator")        -- Winkey+Shift+t: Launch terminal
            -- Multi-monitor navigation
            , ("M-<Right>", nextScreen)               -- Winkey+Right: Focus next screen
            , ("M-<Left>",  prevScreen)               -- Winkey+Left: Focus previous screen
            -- Workspace navigation
            , ("M-<Up>", nextWS)    -- Winkey+Up: Switch to next workspace
            , ("M-<Down>", prevWS)  -- Winkey+Down: Switch to previous workspace
            , ("M-S-<Down>", shiftToNext >> nextWS)   -- Winkey+Shift+Down: Move focused window to next workspace + switch
            , ("M-S-<Up>", shiftToPrev >> prevWS)     -- Winkey+Shift+Up: Move focused window to previous workspace + switch
            , ("M-S-<Right>", shiftNextScreen)        -- Winkey+Shift+Right: Move window to workspace on next screen
            , ("M-S-<Left>", shiftPrevScreen)         -- Winkey+Shift+Left: Move window to workspace on previous screen
            -- Directional window focus (only tiled windows)
            , ("M3-<Right>", sendMessage $ Go R)      -- Caps Lock+Right: Focus window to right
            , ("M3-<Left>", sendMessage $ Go L)       -- Caps Lock+Left: Focus window to left
            , ("M3-<Up>", sendMessage $ Go U)         -- Caps Lock+Up: Focus window above
            , ("M3-<Down>", sendMessage $ Go D)       -- Caps Lock+Down: Focus window below
            , ("M3-M1-<Right>", sendMessage $ Go R)   -- Caps Lock+Alt+Right: Alternate directional focus
            , ("M3-M1-<Left>", sendMessage $ Go L)    -- Caps Lock+Alt+Left
            , ("M3-M1-<Up>", sendMessage $ Go U)      -- Caps Lock+Alt+Up
            , ("M3-M1-<Down>", sendMessage $ Go D)    -- Caps Lock+Alt+Down
            -- Workspace toggle & empty workspace
            , ("M-z", toggleWS)                        -- Winkey+z: Toggle to last workspace
            , ("M-S-e", moveTo Next emptyWS)           -- Winkey+Shift+e: Move to first empty workspace
            -- Master area resize
            , ("M-]", sendMessage MirrorShrink)        -- Winkey+]: Shrink master area
            , ("M-[", sendMessage MirrorExpand)        -- Winkey+[: Expand master area
            -- Status bar toggle
            , ("<F12>", sendMessage ToggleStruts)      -- F12: Toggle status bar
            -- Scratchpads
            , ("C-`", namedScratchpadAction scratchpads "konsole")      -- Ctrl+`: Terminal
            , ("M-`", namedScratchpadAction scratchpads "kate")         -- Winkey+`: Editor
            , ("M1-`", namedScratchpadAction scratchpads "chromium")    -- Alt+`: Browser
            , ("M3-`", namedScratchpadAction scratchpads "htop")        -- Caps Lock+`: System monitor
            , ("M3-1", namedScratchpadAction scratchpads "pavucontrol") -- Caps Lock+1: Sound control
            , ("M3-2", namedScratchpadAction scratchpads "cool-retro-term") -- Caps Lock+2: Retro terminal
            -- Window prompts
            , ("M-S-g", windowPrompt def Goto wsWindows)                 -- Winkey+Shift+g: Go to window in current workspace
            , ("M-S-b", windowPrompt myXPConfig Goto allWindows)        -- Winkey+Shift+b: Go to any window
            , ("M-S-m", workspacePrompt def (windows . W.shift))        -- Winkey+Shift+m: Move window to workspace
            , ("M3-g", windowPrompt def Goto wsWindows)                 -- Caps Lock+g: Go to window in current workspace
            , ("M3-b", windowPrompt myXPConfig Goto allWindows)        -- Caps Lock+b: Go to any window
            , ("M3-m", workspacePrompt def (windows . W.shift))         -- Caps Lock+m: Move window to workspace
            -- Toggle / view workspaces
            , ("M3-e", toggleOrViewNoSP "3:emacs")   -- Caps Lock+e: Toggle / view workspace 3:emacs
            , ("M-x e", toggleOrViewNoSP "3:emacs")   -- Winkey+x then e: Toggle / view workspace 3:macs
            , ("M-x 2", toggleOrViewNoSP "2:$>_")    -- Winkey+x then 2: Toggle / view workspace 2:$>_
        ]
Filename: None. Size: 21kb. View raw, , hex, or download this file.

This paste expires on 2025-11-18 19:24:16.484967. Pasted through web.