XMonad

~/.xmonad/xmonad.hs

Rina Kawakita 2018. 6. 22. 21:17

https://xmonad.org

What is xmonad?

 

xmonad is a dynamically tiling X11 window manager that is written and configured in Haskell. In a normal WM, you spend half your time aligning and searching for windows. xmonad makes work easier, by automating this.

 

What's new?

 

Why should I use xmonad?

xmonad is tiling.
xmonad automates the common task of arranging windows, so you can concentrate on getting stuff done.
xmonad is minimal.
out of the box, no window decorations, no status bar, no icon dock. just clean lines and efficiency.
xmonad is stable.
haskell + smart programming practices guarantee a crash-free experience.
xmonad is extensible.
it sports a vibranextension library, including support for window decorations, status bars, and icon docks.
xmonad is featureful.
core features like per-screen workspaces, true xinerama support and managehooks can't be found in any other wm.
xmonad is easy.
we work hard to make common configuration tasks one-liners.
xmonad is friendly.
an active, friendly mailing list and irc channel are waiting to help you get up and running.
* keyboard based window manager
* layout based window manager
* mininal & fast 
 
 
Cheat Sheet 

 

 

 

~/.xmonad/xmonad.hs

 

-------------------------------------------------------------------------------
--                  __  ____  __                       _                     --
--                  \ \/ /  \/  | ___  _ __   __ _  __| |                    --
--                   \  /| |\/| |/ _ \| '_ \ / _` |/ _` |                    --
--                   /  \| |  | | (_) | | | | (_| | (_| |                    --
--                  /_/\_\_|  |_|\___/|_| |_|\__,_|\__,_|                    --
--                                                                           --
-------------------------------------------------------------------------------
-- File         : ~/.xmonad/xmonad.hs     (xmonad 0.15)                      --
-- referenced   : http://xmonad.org/documentation.html                       --
-- last updated : 2018-10-15                                                 --
-- by nietz                                                                  --
-------------------------------------------------------------------------------
--
-- xmonad example config file.
-- /usr/share/x86_64-linux-ghc-8.0.1/xmonad-0.15/man/xmonad.hs
--
-- A template showing all available configuration hooks,
-- and how to override the defaults in your own xmonad.hs conf file.
--
-- Normally, you'd only override those defaults you care about.
--
-------------------------------------------------------------------------------
-- Import statement                                                         {{{
-------------------------------------------------------------------------------
--{-# LANGUAGE DeriveDataTypeable #-}
--
-- Default Config
import XMonad
import Data.Monoid
import System.Exit

import qualified XMonad.StackSet as W
import qualified Data.Map        as M

-- Application
import Control.Monad

-- Keys move, resize Window
import XMonad.Actions.FloatKeys                         -- http://www.eng.uwaterloo.ca/~aavogt/xmonad/docs/xmonad-contrib/XMonad-Actions-FloatKeys.html
import qualified XMonad.Actions.FlexibleResize as Flex  -- Resize floating windows from any corner.

import XMonad.ManageHook

-- For JumpToLayout keybinding. "hiding" necessary for LayoutCombinators.
--import XMonad hiding ( (|||) )
--import XMonad.Layout.LayoutCombinators  -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutCombinators.html
--import XMonad.Layout.Named              -- (Deprecated) instead XMonad.Layout.Renamed http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Named.html
import XMonad.Layout.Renamed              -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Renamed.html

-- Window Layout Mode
import XMonad.Layout
import XMonad.Layout.ResizableTile      -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ResizableTile.html
import XMonad.Layout.Circle             -- https://hackage.haskell.org/package/xmonad-contrib-0.12/docs/XMonad-Layout-Circle.html
import XMonad.Layout.ThreeColumns       -- http://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Layout-ThreeColumns.html
import XMonad.Layout.Grid               -- https://hackage.haskell.org/package/xmonad-contrib-0.12/docs/XMonad-Layout-Circle.html
import XMonad.Layout.BinarySpacePartition
import XMonad.Layout.Simplest
import XMonad.Layout.SimplestFloat
import XMonad.Layout.SimpleFloat        -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-SimpleFloat.html#t:SimpleDecoration
import XMonad.Layout.NoBorders
import XMonad.Layout.Gaps               -- https://hackage.haskell.org/package/xmonad-contrib-0.12/docs/XMonad-Layout-Gaps.html
import XMonad.Layout.Fullscreen
import XMonad.Layout.ToggleLayouts      -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ToggleLayouts.html
import XMonad.Layout.MultiToggle        -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-MultiToggle.html
import XMonad.Layout.MultiToggle.Instances
import XMonad.Layout.PerWorkspace
import XMonad.Layout.Spacing
import XMonad.Layout.Gaps               -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Gaps.html
import XMonad.Layout.Minimize           -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Minimize.html
import XMonad.Layout.Maximize           -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Maximize.html
import XMonad.Layout.Monitor            -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Monitor.html
import XMonad.Layout.PositionStoreFloat -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-PositionStoreFloat.html
import XMonad.Layout.NoFrillsDecoration
import XMonad.Layout.BorderResize
import XMonad.Layout.WorkspaceDir       -- http://hackage.haskell.org/package/xmonad-contrib-0.15/docs/XMonad-Layout-WorkspaceDir.html

--import XMonad.Layout.WindowArranger   -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-WindowArranger.html#t:WindowArranger

-- Key Binding
import XMonad.Util.Run                  -- customKeys binding
import XMonad.Util.CustomKeys           -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-CustomKeys.html#v:customKeys
import XMonad.Actions.CycleWS
import XMonad.Actions.Submap
import XMonad.Actions.NoBorders

-- Window Menu, management  action
import XMonad.Actions.WindowMenu
import XMonad.Actions.UpdatePointer
import XMonad.Actions.WindowBringer
import XMonad.Actions.SpawnOn
import XMonad.Actions.CycleWS
import XMonad.Actions.PhysicalScreens
import XMonad.Actions.WindowGo
import XMonad.Actions.GridSelect        -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-GridSelect.html
import XMonad.Actions.WithAll           -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-WithAll.html
import XMonad.Actions.SinkAll           -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-SinkAll.html
import XMonad.Actions.Minimize

-- Divide a single screen into multiple screens, multiple screens into single screeen span 
import XMonad.Layout.LayoutScreens
import XMonad.Layout.TwoPane

-- XF86 Extra keys
import Graphics.X11.ExtraTypes.XF86

-- Dzen Status bar
import Dzen

-- Manage Hooks
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.Minimize
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.UrgencyHook
import XMonad.Hooks.ManageHelpers       -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html 
import XMonad.Hooks.SetWMName
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.PositionStoreHooks  -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-PositionStoreHooks.html

-- Addtional Package
import XMonad.Util.EZConfig             -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-EZConfig.html
import XMonad.Util.WorkspaceCompare
import XMonad.Util.NamedScratchpad      --http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-NamedScratchpad.html

-- Themes and stuff
import XMonad.Layout.SimpleDecoration   -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-SimpleDecoration.html
import XMonad.Layout.Decoration
import XMonad.Layout.DecorationMadness  -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-DecorationMadness.html
import XMonad.Layout.ImageButtonDecoration
import XMonad.Util.Image
import XMonad.Util.Themes
import XMonad.Util.Loggers              -- for ppExtras: http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-Loggers.html

-- Flexible and general compositing interface than FadeInactive
import XMonad.Hooks.FadeWindows

-- A prompt for XMonad which will run a program, open a file, or raise an
-- already running program, depending on context.
import XMonad.Prompt                    -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Prompt.html
import XMonad.Prompt.RunOrRaise
import XMonad.Prompt.Shell
import XMonad.Prompt.XMonad
import XMonad.Prompt.Window             -- pops up a prompt with window names
import XMonad.Actions.Commands (defaultCommands)
import XMonad.Actions.Search            -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-Search.html
import Data.Maybe (fromMaybe)

-- System
import System.IO
import XMonad.Util.Replace (replace)
import Control.Monad (when)
import System.Environment (getArgs)


--------------------------------------------------------------------------- }}}
-- Variables                                                                {{{
-------------------------------------------------------------------------------
-- definee base16 color: systhwave theme
--
color0   = "#33303b"
color1   = "#87404f"
color2   = "#4c9982"
color3   = "#71949a"
color4   = "#615772"
color5   = "#783e57"
color6   = "#554757"
color7   = "#c0a79a"
color8   = "#2f2c37"
color9   = "#87404f"
color10  = "#4c9982"
color11  = "#71949a"
color12  = "#615772"
color13  = "#783e57"
color14  = "#554757"
color15  = "#c0a79a"
colorbg0 = "#312e39"
colorbg1 = "#c0a79a"
colorfg0 = "#ffffff"
colorfg1 = "#ce260b"

type Hex = String
type ColorCode = (Hex,Hex)
type ColorMap = M.Map Colors ColorCode

data Colors = Black | Red | Green | Yellow | Blue | Magenta | Cyan | White | BG |FG
    deriving (Ord,Show,Eq)

colors :: ColorMap
colors = M.fromList
    [ (Black   , (color0,   color8  ))
    , (Red     , (color1,   color9  ))
    , (Green   , (color2,   color10 ))
    , (Yellow  , (color3,   color11 ))
    , (Blue    , (color4,   color12 ))
    , (Magenta , (color5,   color13 ))
    , (Cyan    , (color6,   color14 ))
    , (White   , (color7,   color15 ))
    , (BG      , (colorbg0, colorbg1))
    , (FG      , (colorfg0, colorfg1))
    ]

myColor :: Colors -> Int -> Hex
myColor color n =
    case M.lookup color colors of
        Nothing -> "#000000"
        Just (c1,c2) -> if n == 0
                        then c1
                        else c2

-- The preferred terminal program, which is used in a binding below and by
-- certain contrib modules.
-- 
myTerminal :: String
myTerminal = "urxvt"
--myTerminal = "gnome-terminal"

-- 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

-- Width of the window border in pixels.
--
myBorderWidth :: Dimension
myBorderWidth  = 6

-- 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 :: KeyMask
myModMask = mod4Mask

-- Border colors for unfocused and focused windows, respectively.
--
myFocusedBorderColor , myNormalBorderColor :: String
myFocusedBorderColor = (myColor Magenta 0) --"#870000" --"#9144ab"
myNormalBorderColor  = (myColor BG      0) --"#312e39" --"#33303b" --"#3a3a3a" --"#a3a3a3"

-- Font Setting
--
myGSFont , myDzenFont , myPromptFont , myThemeFont , myButtonThemeFont, myDmenuFont :: String
-- gridSelect Font
myGSFont            = "xft:Noto Sans CJK KR:bold:pixelsize=10"   --"xft:SpoqaHanSansJP:Bold:pixelsize=12"
-- dzen Font
myDzenFont          = "Noto Sans CJK KR:bold:pixelsize=10"       -- Dzen is not xft.
-- Prompt Font
myPromptFont        = "xft:Hack:bold:pixelsize=10,xft:NanumGothicCoding:bold:pixelsize=10"
-- Theme Font
myThemeFont         = "xft:Noto Sans CJK KR:bold:pixelsize=10,xft:Hack:bold:pixelsize=10"
myButtonThemeFont   = "xft:Noto Sans CJK KR:bold:pixelsize=10,xft:Hack:bold:pixelsize=10"
-- Dmenu2 Font
myDmenuFont         = "Source Han Sans KR:bold:pixelsize=12"

-- Extra Varaibles
myXResolution       = 1920
myYResolution       = 1080
myTopPanelHeight    = 16
myBottomPanelHeight = 16
myDefaultSpacing    = 0
myDefaultGaps       = 0

-- | A green monochrome colorizer based on window class
greenColorizer = colorRangeFromClassName
                  black            -- lowest inactive bg
                  (0x70,0xFF,0x70) -- highest inactive bg
                  black            -- active bg
                  white            -- inactive fg
                  white            -- active fg
    where black = minBound
          white = maxBound

-- | A synthwave monochrome colorizer based on window class
myGoToSelectedColorizer  :: Window -> Bool -> X (String, String)
myGoToSelectedColorizer  = colorRangeFromClassName
                  (0x31,0x2e,0x39) -- lowest inactive bg
                  (0x31,0x2e,0x39) -- highest inactive bg
                  (0x78,0x3e,0x57) -- active bg
                  (0xc0,0xa7,0x9a) -- inactive fg
                  (0xff,0xff,0xff) -- active fg

myBringSelectedColorizer :: Window -> Bool -> X (String, String)
myBringSelectedColorizer = colorRangeFromClassName
                  (0x31,0x2e,0x39) -- lowest inactive bg
                  (0x31,0x2e,0x39) -- highest inactive bg
                  (0x61,0x57,0x72) -- active bg
                  (0xc0,0xa7,0x9a) -- inactive fg
                  (0xff,0xff,0xff) -- active fg

-- gridSelect select Workspace layout
wsconfig            = def
    { gs_cellheight   = 30
    , gs_cellwidth    = 300
    , gs_cellpadding  = 16
    , gs_originFractX = 0.5
    , gs_originFractY = 0.0
    , gs_font         = myGSFont
    }

-- gridSelect move Workspace layout
wsconfig2           = def
    { gs_cellheight   = 30
    , gs_cellwidth    = 300
    , gs_cellpadding  = 16
    , gs_originFractX = 1.5
    , gs_originFractY = 0.0
    , gs_font         = myGSFont
    }

-- gridSelect select window layout
wiconfig colorizer  = (buildDefaultGSConfig myGoToSelectedColorizer )
--wiconfig = defaultGSConfig
    { gs_cellheight   = 30
    , gs_cellwidth    = 200
    , gs_cellpadding  = 16
    , gs_originFractX = 0.5
    , gs_originFractY = 0.5
    , gs_font         = myGSFont
  }

-- gridSelect bring window layout
wiconfig2 colorizer = (buildDefaultGSConfig myBringSelectedColorizer)
--wiconfig2 = defaultGSConfig
    { gs_cellheight   = 30
    , gs_cellwidth    = 200
    , gs_cellpadding  = 16
    , gs_originFractX = 0.5     --1.0
    , gs_originFractY = 0.3     --0.5
    , gs_font         = myGSFont
    }

-- gridSelect popup menu layout
popupconfig         = def
    { gs_cellheight   = 30
    , gs_cellwidth    = 200
    , gs_cellpadding  = 8
    , gs_originFractX = 0.5
    , gs_originFractY = 0.5
    , gs_font         = myGSFont
    }

-- spawnSelected Redefine
spawnSelected' :: [(String, String)] -> X ()
spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
    where conf = popupconfig


---------------------------------------------------------------------------}}}
-- Prompt : data XPConfig                                                   {{{
------------------------------------------------------------------------------
-- Prompt Theme configuration
myPromptFgColor             = myColor BG      1
myPromptBgColor             = myColor Black   0
myPromptBgHLight            = myColor Magenta 0
myPromptFgHLight            = myColor White   0

--instance XPrompt Shell where
    --showXPrompt Shell = "dRun: "

-- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Prompt.html#t:XPConfig
myPromptConfig :: XPConfig
myPromptConfig = def
    { XMonad.Prompt.font        = myPromptFont
    , bgColor                   = myPromptBgColor
    , fgColor                   = myPromptFgColor
    , bgHLight                  = myPromptBgHLight
    , fgHLight                  = myPromptFgHLight
    , borderColor               = myNormalBorderColor
    , promptBorderWidth         = 1
    , XMonad.Prompt.height      = 16
    , XMonad.Prompt.position    = Top 
    , alwaysHighlight           = False
    , historySize               = 20
    , historyFilter             = id
    , promptKeymap              = defaultXPKeymap 
    --, completionKey             = xK_Tab              -- xmonad 0.12
    , completionKey             = (0, xK_Tab)           -- xmonad 0.13
    , changeModeKey             = xK_grave
    , defaultText               = []
    , autoComplete              = Nothing
    , showCompletionOnTab       = False
    , searchPredicate           = isPrefixOf
    }


----------------------------------------------------------------------------}}}
-- Theme configuration                                                      {{{
-------------------------------------------------------------------------------
--
myTheme :: Theme
myTheme = def
    { activeColor         = myColor Magenta 0
    , inactiveColor       = myColor Black   1
    , urgentColor         = myColor BG      1
    , activeBorderColor   = myColor Magenta 0
    , inactiveBorderColor = myColor Black   1
    , activeTextColor     = myColor White   1
    , inactiveTextColor   = myColor Blue    0
    , urgentTextColor     = myColor Red     0
    , fontName            = myThemeFont
    , decoWidth           = 1920
    , decoHeight          = 16
    , windowTitleAddons   = []
    , windowTitleIcons    = []
    }

myButtonTheme :: Theme
myButtonTheme = defaultThemeWithImageButtons
    { activeColor         = myColor Magenta 0
    , inactiveColor       = myColor Black   1
    , urgentColor         = myColor BG      1
    , activeBorderColor   = myColor Magenta 0
    , inactiveBorderColor = myColor Black   1
    , activeTextColor     = myColor White   1
    , inactiveTextColor   = myColor Blue    0
    , urgentTextColor     = myColor Red     0
    , fontName            = myButtonThemeFont
    , decoHeight          = 18
    , windowTitleIcons    = [ (menuButton , CenterLeft   3)
                            , (closeButton, CenterRight  3)
                            , (maxiButton , CenterRight 18)
                            , (miniButton , CenterRight 33)
                            ]
    }
    where
        convertToBool' :: [Int] -> [Bool]
        convertToBool' = map (\x -> x == 1)
        convertToBool :: [[Int]] -> [[Bool]]
        convertToBool  = map convertToBool'
        menuButton' :: [[Int]]
        menuButton' =  [[0,0,0,0,0,0,0,0,0,0],
                        [0,1,0,0,0,0,0,0,1,0],
                        [0,0,1,1,0,0,1,1,0,0],
                        [0,0,1,0,0,0,0,1,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,1,0,0,0,0,1,0,0],
                        [0,0,1,1,0,0,1,1,0,0],
                        [0,1,0,0,0,0,0,0,1,0],
                        [0,0,0,0,0,0,0,0,0,0]]
        menuButton :: [[Bool]]
        menuButton  = convertToBool menuButton'
        miniButton' :: [[Int]]
        miniButton' =  [[0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,1,1,1,1,1,1,1,1,0],
                        [0,1,1,1,1,1,1,1,1,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0]]
        miniButton :: [[Bool]]
        miniButton  = convertToBool miniButton'
        maxiButton' :: [[Int]]
        maxiButton' =  [[0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,1,1,0,0,0,0],
                        [0,0,0,0,1,1,0,0,0,0],
                        [0,0,0,0,1,1,0,0,0,0],
                        [0,1,1,1,1,1,1,1,1,0],
                        [0,1,1,1,1,1,1,1,1,0],
                        [0,0,0,0,1,1,0,0,0,0],
                        [0,0,0,0,1,1,0,0,0,0],
                        [0,0,0,0,1,1,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0]]
        maxiButton :: [[Bool]]
        maxiButton  = convertToBool maxiButton'
        closeButton' :: [[Int]]
        --closeButton' = [[0,0,0,0,0,0,0,0,0,0],
          --              [0,1,1,0,0,0,0,1,1,0],
            --            [0,1,1,1,0,0,1,1,1,0],
              --          [0,0,1,1,0,0,1,1,0,0],
                --        [0,0,0,1,1,1,1,0,0,0],
                  --      [0,0,0,1,1,1,1,0,0,0],
                    --    [0,0,1,1,0,0,1,1,0,0],
                      --  [0,1,1,1,0,0,1,1,1,0],
                        --[0,1,1,0,0,0,0,1,1,0],
                        --[0,0,0,0,0,0,0,0,0,0]]
        closeButton' = [[0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,1,1,1,1,1,1,0,0],
                        [0,0,1,1,1,1,1,1,0,0],
                        [0,0,1,1,1,1,1,1,0,0],
                        [0,0,1,1,1,1,1,1,0,0],
                        [0,0,1,1,1,1,1,1,0,0],
                        [0,0,1,1,1,1,1,1,0,0],
                        [0,0,0,0,0,0,0,0,0,0],
                        [0,0,0,0,0,0,0,0,0,0]]
        closeButton :: [[Bool]]
        closeButton = convertToBool closeButton'


----------------------------------------------------------------------------}}}
-- Define the names of all 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]
--myWorkspaces    = ["1","2","3","4","5","6","7","8","9"]

myWorkspaces :: [String]
-- Clicable workspaces : + dzenwsbar
--myWorkspaces = clickable $ 
    --[
    --" 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6:Work ", " 7:Virtual Machine ", " TV ", " Kodi "
    --]
    --where clickable l = [ "^ca(1,xdotool key super+" ++ show (n) ++ ")" ++ ws ++ "^ca()" |
                         --(i,ws) <- zip [1..] l,
                         --let n = i ]

-- non-Clickable workspaces : + xmobar clickable set
--myWorkspaces = [ "  일  ", "  이  ", "  삼  ", "  사  ", "  오  ", "  육:Work  ", "  칠:Virtual Machine  ", "  TV  ", "  Kodi  " ]
myWorkspaces = [ "  1  ", "  2  ", "  3  ", "  4  ", "  5  ", "  6:Work  ", "  7:Virtual Machine  ", "  TV  ", "  Kodi  " ]


----------------------------------------------------------------------------}}}
-- Layout                                                                   {{{
-------------------------------------------------------------------------------
-- 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.
--

-- Define default layouts used on most workspaces.
defaultLayouts = avoidStruts ( Circle ||| tiled ||| (gaps [(U,4), (D,4), (L,4), (R,4)] $ spacing 8 $ ThreeColMid 1 (20/100) (56/100)) )
--defaultLayouts = Circle ||| tiled ||| Mirror tiled ||| floatDwmStyle shrinkText myTheme |||  Full     -- Full mode : Border
--defaultLayouts = tiled ||| Mirror tiled ||| floatSimpleDwmStyle ||| Full                              -- Full mode : Border
--defaultLayouts = tiled ||| Mirror tiled ||| noBorders (fullscreenFull Full)                           -- Full mode : no Borders
--defaultLayouts = noBorders (fullscreenFull Full) ||| tiled ||| Mirror tiled 
    where
        -- default tiling algorithm partitions the screen into two panes
        --tiled   = gaps [(U,5), (D,5), (R,5), (L,5)] $ spacing 2 $ Tall nmaster delta ratio            -- gap all direction 5
        tiled   = spacing 0 $ ResizableTall nmaster delta ratio []
        --tiled   = Tall nmaster delta ratio
        -- The default number of windows in the master pane
        nmaster = 1 
        -- Default proportion of screen occupied by master pane
        ratio   = 3/5
        -- Percent of screen to increment by when resizing panes
        delta   = 3/100

--- Define layout for specific workspaces

mediaLayout = avoidStruts gaptiled
    where
        --gaptiled = gaps [(U, 0), (D,320), (L,16)] $ spacing 0 $ ResizableTall nmaster delta ratio []
        gaptiled = gaps [(U,0), (D,262), (L,0), (R,0)] $ spacing 0 $ ResizableTall nmaster delta ratio []
        nmaster = 0
        ratio = 3/4
        delta = 1/4

fullLayout = noBorders (fullscreenFull Full)

--floatLayout = simpleFloat ||| noBorders (fullscreenFull Full)
--floatLayout = simpleFloat' shrinkText myTheme ||| Full
--floatLayout = floatDwmStyle shrinkText myTheme ||| Full
--floatLayout = floatSimpleTabbed ||| Full
--floatLayout = floatTabbed shrinkText myTheme ||| Full
--floatLayout = floatDwmStyle shrinkText myTheme ||| Full
--floatLayout = avoidStruts (floatDefault shrinkText myTheme ||| Full)
--floatLayout = avoidStruts $ gaps [(U,20), (D,20), (L,50), (R,50)] $ spacing 20 $ emptyBSP ||| floatDwmStyle shrinkText myTheme
--floatLayout = avoidStruts $ gaps [(U,20), (D,20), (L,50), (R,50)] $ spacing 20 emptyBSP ||| noBorders ( simpleFloat' shrinkText myTheme )
--floatLayout = simpleDeco shrinkText myTheme (layoutHook defaultConfig)
--floatLayout = floatingDeco $ borderResize $ positionStoreFloat
               --where floatingDeco l = noFrillsDeco shrinkText defaultTheme l
floatLayout = avoidStruts $ gaps [(U,8), (D,8), (L,8), (R,8)] $ spacing 16 emptyBSP |||
              --noBorders ( imageButtonDeco shrinkText myButtonTheme $ simpleFloat' shrinkText myTheme { decoHeight =0 } ) |||
              noBorders ( imageButtonDeco shrinkText myButtonTheme simplestFloat )  |||
              noBorders ( imageButtonDeco shrinkText myButtonTheme positionStoreFloat )

tvLayout = avoidStruts
    (noBorders (tiled) ||| gaptiled ||| Circle ||| noBorders (Grid) ||| noBorders (fullscreenFull Full))
    where
        tiled = spacing 0 $ ResizableTall nmaster delta ratio []
        --nmaster = 2
        --ratio = 1/2
        --delta = 1/4
        nmaster = 1
        ratio = 3/4
        delta = 1/4
        gaptiled = gaps [(U,4), (D,4), (R,4), (L,4)] $ spacing 8 $ Tall nmaster delta ratio

-- Put all layouts together
myLayouts = workspaceDir "/home/nietz"                            $
            lessBorders OnlyScreenFloat                 $   -- OnlyFloat, Never, EmptyScreen, OtherIndicated, Screen
            smartBorders                                $
            borderResize                                $
            minimize $ maximize                         $
            mkToggle (NOBORDERS ?? FULL ?? EOT)         .
            mkToggle (single NBFULL)                    .
            mkToggle (single MIRROR)                    $
            toggleLayouts (avoidStruts $ Full)          $
            --toggleLayouts Full                        $
            --toggleLayouts (avoidStruts $ noBorders Full) $
            onWorkspace (myWorkspaces !! 8) fullLayout  $
            onWorkspace (myWorkspaces !! 7) tvLayout    $
            onWorkspace (myWorkspaces !! 6) fullLayout  $
            onWorkspace (myWorkspaces !! 5) floatLayout $
            onWorkspace (myWorkspaces !! 4) mediaLayout $
            defaultLayouts

----------------------------------------------------------------------------}}}
-- Named ScratchPads                                                        {{{
-------------------------------------------------------------------------------
--
-- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-NamedScratchpad.html
-- Scratchpad Everything:  https://pbrisbin.com/posts/scratchpad_everything/
--
myScratchPads :: [NamedScratchpad]
myScratchPads = [ NS "terminal" spawnTerm   findTerm   manageTerm     -- one scratchpad
                , NS "mixer"    spawnMixer  findMixer  manageMixer    -- and a second
                , NS "video"    spawnVideo  findVideo  manageVideo    -- and a third
                , NS "player"   spawnPlayer findPlayer managePlayer   -- and a 4th
                , NS "mpd"      spawnMpd    findMpd    manageMpd      -- and a 5th
                ]
    where
        role = stringProperty "WM_WINDOW_ROLE"

        spawnTerm   = myTerminal ++ " -b 15 -name scratchpad -fn 'xft:Iosevka Nerd Font Mono:style=Regular:pixelsize=22,xft:NanumGothicCoding:pixelsize=22'" ++ " -fb 'xft:Iosevka Nerd Font Mono:style=Bold:pixelsize=22,xft:NanumGothicCoding:Bold:pixelsize=24'"         -- launch my scratchpad terminal
        findTerm    = resource  =? "scratchpad"                 -- its window will be named "scratchpad" (see above)
        manageTerm  = customFloating $ W.RationalRect l t w h   -- and I'd like it fixed using the geometry below
            where
            -- reusing these variables is ok since they're confined to their own 
            -- where clauses 
            h = 0.75    --0.65                                  -- height, 65%
            w = 0.75    --0.68                                  -- width,  68%
            t = (1 - h)/2                                       -- centered top/bottom
            l = (1 - w)/2                                       -- centered left/right

        spawnMixer   = "urxvt -name pulsemixer -e pulsemixer"                                                       -- launch my pulsemixer
        findMixer    = resource =? "pulsemixer" <||> title =? "pulsemixer"                                          -- its window has a ClassName of "mixer"
        manageMixer  = customFloating $ W.RationalRect l t w h                                                      -- and I'd like it fixed using the geometry below:
            where
                h = 0.6                                         -- height, 60%
                w = 0.6                                         -- width,  60%
                t = (1 - h)/2                                   -- centered top/bottom
                l = (1 - w)/2                                   -- centered left/right

        -- mpsyt : "set playerargs --x11-name mpsyt"
        spawnVideo   = "mpv --x11-name mpsyt --ytdl-format best --no-resume-playback $(xclip -o)"                   -- launch mpv for youtube (resolusin 1280x720)
        findVideo    = resource  =? "mpsyt" <&&> className =? "mpv"                                                 -- its window will be named "video" (see above)
        manageVideo  = ((customFloating $ W.RationalRect l t w h) <+> doF W.focusDown)                              -- and I'd like it fixed using the geometry below, then focus down, mpv no focus
            where
            -- reusing these variables is ok since they're confined to their own 
            -- where clauses 
            h = 0.29     --0.24                                            -- height, 24%
            w = 0.29     --0.24                                            -- width,  24%
            t = (1 - h) - (myBottomPanelHeight / myYResolution) -- bottom right edge: bottom xmobar height=16, y resoulution=1080
            l = 1 - w                                           -- right, left/right

        spawnPlayer  = "mpv --x11-name livetv --profile tv --no-resume-playback --playlist-pos 19 channels.m3u"     -- launch mpv for livetv mpv
        findPlayer   = resource  =? "livetv" <&&> className =? "mpv"                                                -- its window will be named "player" (see above)
        managePlayer = customFloating $ W.RationalRect l t w h                                                      -- and I'd like it fixed using the geometry below
            where
            -- reusing these variables is ok since they're confined to their own 
            -- where clauses 
            h = 0.29    --0.24                                            -- height, 24%
            w = 0.29    --0.24                                            -- width,  24%
            --t = 0 + (myTopPanelHeight / myYResolution)          -- top right edge: top xmobar height=16, y resoulution=1080
            --l = 1 - w                                           -- right, left/right
            t = (1 - h) - (myBottomPanelHeight / myYResolution) -- bottom right edge: bottom xmobar height=16, y resoulution=1080
            l = 1 - w                                           -- right, left/right

        spawnMpd   = myTerminal ++ " -name mpd -e $HOME/.local/bin/ncmpcpp-tmux"                                    -- launch my scratchpad ncmpcpp
        findMpd    = resource  =? "mpd"                                                                             -- its window will be named "mpd" (see above)
        manageMpd  = customFloating $ W.RationalRect l t w h                                                        -- and I'd like it fixed using the geometry below
            where
            -- reusing these variables is ok since they're confined to their own 
            -- where clauses 
            h = 0.7                                             -- height, 70%
            w = 0.8                                             -- width,  80%
            t = (1 - h)/2                                       -- centered top/bottom
            l = (1 - w)/2                                       -- centered left/right


-- NamedScratchPad Pass
notSP :: X (WindowSpace -> Bool)
notSP = return $ ("NSP" /=) . W.tag

nextWS' :: X ()
nextWS' = moveTo Next (WSIs notSP)
prevWS' :: X ()
prevWS' = moveTo Prev (WSIs notSP)


----------------------------------------------------------------------------}}}
-- Window rules: Manage Hook                                                {{{
-------------------------------------------------------------------------------
-- 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.
--
-- The class name of an application corresponds to the first 
-- value of WM_CLASS (“Pidgin”).
-- The resource corresponds to the second value of WM_CLASS (also “Pidgin”). 
-- The title corresponds to WM_NAME (“Buddy List”).

-- Define the workspace on application has to go to
myManageHook :: ManageHook
myManageHook = (composeAll . concat $
    [
        ---------------------------------------------------------------------------------
        --- General Condition
        ---------------------------------------------------------------------------------
          [ className =?  c <||> title=?  c --> doF (W.shift (myWorkspaces !! 0))   | c <- myClassWebShifts      ]
        , [ className =?  c --> doF (W.shift (myWorkspaces !! 1))                   | c <- myClassBrowseShifts   ]
        , [ resource  =?  r --> doF (W.shift (myWorkspaces !! 2))                   | r <- myClassChatShifts     ]
        , [ className =?  c --> doF (W.shift (myWorkspaces !! 3))                   | c <- myClassTerminalShifts ]
        , [ className =?  c --> doF (W.shift (myWorkspaces !! 4))                   | c <- myClassDevShifts      ]
        , [ className =?  c --> doF (W.view  (myWorkspaces !! 5))                   | c <- myClassWorkShifts     ]
        , [ className =?  c --> doF (W.shift (myWorkspaces !! 5))                   | c <- myClassWorkShifts     ]
        , [ className =?  c --> doF (W.view  (myWorkspaces !! 8))                   | c <- myClassXinerama       ]
        , [ className =?  c --> doF (W.shift (myWorkspaces !! 8))                   | c <- myClassXinerama       ]
        --, [ className =?  c --> doFullFloat                                       | c <- myClassXinerama       ]
        , [ className =?  c --> doCenterFloat                                       | c <- myClassCFloats        ]
        , [ className =?  c --> doRectFloat (W.RationalRect 0.759 0.758 0.24 0.24)  | c <- myClassRFloats        ]
        , [ className =?  c --> doIgnore                                            | c <- myClassIgnore         ]
        , [ resource  =?  r --> doIgnore                                            | r <- myClassIgnore         ]
        --, [ resource  =?  r --> doIgnore                                            | r <- myClassIgnore         ]
        --
        ---------------------------------------------------------------------------------
        --- Startup hooks condition apps
        ---------------------------------------------------------------------------------
        , [ title =? "autoload"     --> doF (W.shift (myWorkspaces !! 3)) ]
        --, [ className =? "mpv" --> doF (W.shift (myWorkspaces !! 3)) ]
        , [ title =? "ncmpcpp_tmux" --> doF (W.shift (myWorkspaces !! 3)) ]
        , [ title =? "ncmpcpp_tmux" --> doF (W.view  (myWorkspaces !! 3)) ]
        --
        , [ className =? "Clock" <&&> title     =? "oclock"                            --> doRectFloat (W.RationalRect (1-0.10) ((1-0.15)-(16/1080)) 0.10 0.15) ]
        , [ className =? "Orage" <&&> title     =? "Orage"                             --> doRectFloat (W.RationalRect (1-0.10) ((1-0.15)-(16/1080)) 0.10 0.15) ]
        , [ className =? "URxvt" <&&> resource  =? "cava_back"                         --> doRectFloat (W.RationalRect (0     ) ((0     )+(16/1080)) 0.25 0.12) ]
        , [ className =? "Orage" <&&> title    /=? "Orage"                             --> doCenterFloat                                                        ]

        ---------------------------------------------------------------------------------
        --- General mpv
        ---------------------------------------------------------------------------------
            --t = 0 + (myTopPanelHeight / myYResolution)          -- top right edge: top xmobar height=16, y resoulution=1080
            --l = 1 - w                                           -- right, left/right
            --l = 1 - w                                           -- right, left/right
            --t = (1 - h) - (myBottomPanelHeight / myYResolution) -- bottom right edge: bottom xmobar height=16, y resoulution=1080
        , [ className =? "mpv"   <&&> resource =? "music" --> doRectFloat (W.RationalRect (1-0.145) (0 + (myTopPanelHeight / myYResolution) ) 0.145 0.258)                     ]   --for mpv mp3 cover art, --x11-name music, --geometry=10%
        , [ className =? "mpv"   <&&> resource =? "jav" --> doRectFloat (W.RationalRect 0 0 0.29 0.29)                     ]   --for 
        , [ className =? "mpv"   <&&> resource =? "image" --> ( doRectFloat (W.RationalRect (1-0.24) (0 + (myTopPanelHeight / myYResolution) ) 0.24 0.24) <+> doF W.focusDown ) ]   --for ranger img display, --x11-name image
        , [ className =? "mpv"   <&&> resource /=? "mpsyt" <&&> resource /=? "livetv" <&&> resource /=? "youtube-viewer" --> doCenterFloat                                     ]


        ---------------------------------------------------------------------------------
        --- $ mpv --x11-name mpsyt   -- mpsyt args : "set playerargs --x11-name mpsyt"
        ---------------------------------------------------------------------------------
        --, [ className =? "mpv"   <&&> resource =? "mpsyt"                              --> doF W.focusDown                                                      ]
        --, [ className =? "mpv"   <&&> resource =? "mpsyt" <&&> resource /=? "livetv"   --> doSideFloat(SE)                                                      ]
        , [ className =? "mpv"   <&&> resource =? "mpsyt" <&&> resource /=? "livetv"  --> doIgnore                                                              ]  -- mpv config file : direct config

        ---------------------------------------------------------------------------------
        --- $ youtube-viewer --video-player=mpv --append-arg="--x11-name youtube-viewer"
        ---------------------------------------------------------------------------------
        , [ className =? "mpv"   <&&> resource =? "youtube-viewer"                     --> doF (W.shift (myWorkspaces !! 1))                                    ]

        ---------------------------------------------------------------------------------
        --- BigFont for Remote lirc
        ---------------------------------------------------------------------------------
        , [ className =? "URxvt" <&&> resource  =? "urxvt-big"                         --> (doF (W.view  (myWorkspaces !! 8)) <+> doF (W.shift (myWorkspaces !! 8))) ]

        ---------------------------------------------------------------------------------
        --- Spcific Condition
        ---------------------------------------------------------------------------------
        , [ isDialog            --> doCenterFloat   ]
        , [ isFullscreen        --> doFullFloat     ]
        , [ isKDETrayWindow     --> doIgnore        ]

    ])  <+> namedScratchpadManageHook myScratchPads
        <+> manageDocks
        <+> fullscreenManageHook
        <+> positionStoreManageHook (Just defaultThemeWithImageButtons)
        <+> manageHook def

    where
        -- if non-Clickable workspace, then "doF(W.shift(myWorkspaces !! n))" => "viewShift" or "doShift"
        -- viewShift = doF . liftM2 (.) W.greedyView W.shift
        myClassWebShifts      = [ "W3m", "Uzbl", "Uzbl-core","Opera","vivaldi","qutebrowser", "mutt"             ]
        myClassBrowseShifts   = [ "Spacefm","Pcmanfm"                                                            ]
        myClassChatShifts     = [ "Pidgin","Weechat"                                                             ]
        myClassTerminalShifts = [ "Xterm","UXTerm"                                                               ]
        myClassDevShifts      = [ "I am not programmer"                                                          ]
        myClassWorkShifts     = [ "libreoffice","Openshot","Calculator","shutter","qbittorrent","Qbittorrent"    ]
        myClassIgnore         = [ "desktop", "kdesktop", "desktop_window", "mplayer2", "cava_back"               ]
        myClassXinerama       = [ "Kodi", "kodi", "Kodi.bin","kodi.bin","xbmc", "xbmc.bin"                       ]
        myClassCFloats        = [ "feh", "sxiv", "luakit", "Luakit", "Xmessage", "Gxmessage"                     ]
        myClassRFloats        = [ "Vlc"                                                                          ]



----------------------------------------------------------------------------}}}
-- Key Binding                                                              {{{
-------------------------------------------------------------------------------
-- FOR MULTIMEDIA KEYS RUN:
-- xev | grep -A2 --line-buffered '^KeyRelease' | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p'
-- Then look in /usr/include/X11/XF86keysym.h and look for the name and code.
--
-- Graphics.X11 keysym definitions: https://wiki.haskell.org/Xmonad/Key_codes
-- /usr/include/X11/keysymdef.h

-- Define keys to add
keysToAdd x =
    [
    --- Workspace move, shit append,  Window Close
    -- Close focused window
    ((modMask x, xK_c), kill)
    -- Close focused workspaced all window
    ,  (((modMask x .|. controlMask .|. shiftMask), xK_c    ), killAll :: X())
    -- Shift to previous workspace
    ,  (((modMask x .|. controlMask              ), xK_Left ), prevWS'       )
    --,  (((modMask x .|. controlMask              ), xK_Left ), prevWS        )
    -- Shift to next workspace
    ,  (((modMask x .|. controlMask              ), xK_Right), nextWS'       )
    --,  (((modMask x .|. controlMask              ), xK_Right), nextWS        )
    -- Shift widow to previous workspace
    ,  (((modMask x .|. shiftMask                ), xK_Left ), shiftToPrev   )
    -- Shift to next workspace
    ,  (((modMask x .|. shiftMask                ), xK_Right), shiftToNext   )


    --- Working Window Visible Management
    --, ((modMask x .|. shiftMask, xK_a), windowMenu)
    , ((modMask x .|. shiftMask, xK_a), gridselectWorkspace wsconfig  (\ws -> W.view ws))                 -- select workspace
    , ((modMask x .|. shiftMask, xK_t), gridselectWorkspace wsconfig2 (\ws -> W.view ws . W.shift ws))    -- move current window to selected workspace
    --, ((modMask x .|. shiftMask, xK_s), goToSelected defaultGSConfig)                                   -- show all working apps'name list, if click, then go clicked app. I liked this menu
    --, ((modMask x .|. shiftMask, xK_s), goToSelected wiconfig)                                          -- show all working apps'name list, if click, then go clicked app. I liked this menu
    , ((modMask x .|. shiftMask, xK_s), goToSelected  $ wiconfig  myGoToSelectedColorizer)                -- above same, for custom colorizer 
    --, ((modMask x .|. shiftMask, xK_b), bringSelected wiconfig2)                                        -- bring window list and summon a window you select 
    , ((modMask x .|. shiftMask, xK_b), bringSelected $ wiconfig2 myBringSelectedColorizer)               -- bring window list and summon a window you select 
    , ((modMask x .|. shiftMask, xK_g), gotoMenu)                                                         -- avobe goToSelected same, like dmenu appearence
    , ((modMask x .|. shiftMask, xK_i), bringMenu)                                                        -- bring window, like dmenu appaerance, 


    -- Layout Window move or resize  -> import XMonad.Layout.WindowArranger
    --, (((modMask x .|. controlMask              ), xK_s    ), sendMessage  Arrange         )
    --, (((modMask x .|. controlMask .|. shiftMask), xK_s    ), sendMessage  DeArrange       )
    --, (((modMask x .|. controlMask              ), xK_Left ), sendMessage (MoveLeft      1))
    --, (((modMask x .|. controlMask              ), xK_Right), sendMessage (MoveRight     1))
    --, (((modMask x .|. controlMask              ), xK_Down ), sendMessage (MoveDown      1))
    --, (((modMask x .|. controlMask              ), xK_Up   ), sendMessage (MoveUp        1))
    --, (((modMask x                 .|. shiftMask), xK_Left ), sendMessage (IncreaseLeft  1))
    --, (((modMask x                 .|. shiftMask), xK_Right), sendMessage (IncreaseRight 1))
    --, (((modMask x                 .|. shiftMask), xK_Down ), sendMessage (IncreaseDown  1))
    --, (((modMask x                 .|. shiftMask), xK_Up   ), sendMessage (IncreaseUp    1))
    --, (((modMask x .|. controlMask .|. shiftMask), xK_Left ), sendMessage (DecreaseLeft  1))
    --, (((modMask x .|. controlMask .|. shiftMask), xK_Right), sendMessage (DecreaseRight 1))
    --, (((modMask x .|. controlMask .|. shiftMask), xK_Down ), sendMessage (DecreaseDown  1))
    --, (((modMask x .|. controlMask .|. shiftMask), xK_Up   ), sendMessage (DecreaseUp    1))


    -- Fixed Singgle Layout expand & divide 2 pane
    ,  (((modMask x .|. controlMask .|. shiftMask), xK_x), layoutScreens 1     (fixedLayout [Rectangle 0 0 3840 1080]))
    ,  (((modMask x .|. controlMask .|. shiftMask), xK_d), layoutSplitScreen 2 (TwoPane 0.5  0.5 ))   -- divide single screen to 2 screen
    --,  (((modMask x .|. controlMask .|. shiftMask), xK_f), layoutSplitScreen 2 (TwoPane 0.3  0.7 ))   -- divide single screen to 2 screen
    ,  (((modMask x .|. controlMask .|. shiftMask), xK_f), layoutSplitScreen 2 (TwoPane 0.25  0.75))   -- divide single screen to 2 screen
    ,  (((modMask x .|. controlMask .|. shiftMask), xK_r), layoutScreens 2     (TwoPane 0.25 0.75))
    -- Physical Screen control
    --,  (((modMask x .|. controlMask              ), xK_a), onPrevNeighbour W.view )
    --,  (((modMask x .|. controlMask              ), xK_s), onNextNeighbour W.view )
    --,  (((modMask x .|. controlMask .|. shiftMask), xK_a), onPrevNeighbour W.shift)
    --,  (((modMask x .|. controlMask .|. shiftMask), xK_s), onNextNeighbour W.shift)
    -- Return Default Layout
    ,  (((modMask x .|. controlMask .|. shiftMask), xK_space), rescreen)


    --- Floating Window Movement, Resizing
    -- Window Movement
    , ((modMask x                                , xK_Left        ), withFocused (keysMoveWindow (-10, 0  )))
    , ((modMask x                                , xK_Up          ), withFocused (keysMoveWindow (0  , -10)))
    , ((modMask x                                , xK_Down        ), withFocused (keysMoveWindow (0  , 10 )))
    , ((modMask x                                , xK_Right       ), withFocused (keysMoveWindow (10 , 0  )))
    -- Window Resizing 
    , (((modMask x .|. controlMask .|. shiftMask), xK_Left        ), withFocused (keysResizeWindow    (-10,   0) (0, 0)))
    , (((modMask x .|. controlMask .|. shiftMask), xK_Up          ), withFocused (keysResizeWindow    (0  , -10) (0, 0)))
    , (((modMask x .|. controlMask .|. shiftMask), xK_Down        ), withFocused (keysResizeWindow    (0  ,  10) (0, 0)))   -- urxvt terminal not works
    , (((modMask x .|. controlMask .|. shiftMask), xK_Right       ), withFocused (keysResizeWindow    (10 ,   0) (0, 0)))
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Page_Down), withFocused (keysAbsResizeWindow (10 ,  10) (0, 0)))   -- urxvt down direction not
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Home     ), withFocused (keysAbsResizeWindow (-10, -10) (0, 0)))


    --- Manual Float Corner movement : 
    -- Case : resolution 1920x1080 x2(dual), top panel height=16, no bottom panel, window spacing=2, window border=1
    -- Non-numeric num pad keys, sorted by number 
    -- numPadKeys = [ xK_KP_End,  xK_KP_Down,  xK_KP_Page_Down -- 1, 2, 3
    --              , xK_KP_Left, xK_KP_Begin, xK_KP_Right     -- 4, 5, 6
    --              , xK_KP_Home, xK_KP_Up,    xK_KP_Page_Up   -- 7, 8, 9
    --              , xK_KP_Insert]                            -- 0
    --
    -- Center Position, No resizable
    , ((modMask x,                                 xK_KP_Begin    ), withFocused (keysMoveWindowTo (959 , 547 ) (1/2, 1/2)))    -- Left Screen Center Position. no resizable
    , (((modMask x .|.                 shiftMask), xK_KP_Begin    ), withFocused (keysMoveWindowTo (2879, 547 ) (1/2, 1/2)))    -- Right Screen Center Position. no resizable
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Begin    ), withFocused (keysMoveWindowTo (1916, 547 ) (1/2, 1/2)))    -- Dual Screen Center Position. no resizable
    -- Left Screen Conner Position, No resizable
    , ((modMask x                                , xK_KP_Home     ), withFocused (keysMoveWindowTo (2   , 18  ) (0  , 0  )))    -- Left Screen, Left-Top Conner Position. no resizable
    , ((modMask x                                , xK_KP_Page_Up  ), withFocused (keysMoveWindowTo (1916, 18  ) (1  , 0  )))    -- Left Screen, Rifhtt-Top Conner Position. no resizable
    , ((modMask x                                , xK_KP_End      ), withFocused (keysMoveWindowTo (2   , 1078) (0  , 1  )))    -- Left Screen, Left-Bottom Conner Position. no resizable
    , ((modMask x                                , xK_KP_Page_Down), withFocused (keysMoveWindowTo (1916, 1078) (1  , 1  )))    -- Left Screen, Rifhtt-Bottom Conner Position. no resizable
    -- Right Screen Conner Position, No resizable
    , (((modMask x .|.                 shiftMask), xK_KP_Home     ), withFocused (keysMoveWindowTo (1922, 18  ) (0  , 0  )))    -- Right Screen, Left-Top Conner Position. no resizable
    , (((modMask x .|.                 shiftMask), xK_KP_Page_Up  ), withFocused (keysMoveWindowTo (3836, 18  ) (1  , 0  )))    -- Right Screen, Rifhtt-Top Conner Position. no resizable
    , (((modMask x .|.                 shiftMask), xK_KP_End      ), withFocused (keysMoveWindowTo (1922, 1078) (0  , 1  )))    -- Right Screen, Left-Bottom Conner Position. no resizable
    , (((modMask x .|.                 shiftMask), xK_KP_Page_Down), withFocused (keysMoveWindowTo (3836, 1078) (1  , 1  )))    -- Right Screen, Rifhtt-Bottom Conner Position. no resizable


    -- ResizableTile
    , ((modMask x, xK_a), sendMessage MirrorShrink)
    , ((modMask x, xK_z), sendMessage MirrorExpand)


    -- Toggle Struts : panel visiblity toggle on/off
    , ((modMask x, xK_b                                ), sendMessage ToggleStruts)
    -- Hide all gaps:
    , (((modMask x .|. mod1Mask), xK_b                 ), sendMessage $ SetStruts [] [minBound .. maxBound]) 
    -- Show all gaps:
    , (((modMask x .|. controlMask .|. mod1Mask), xK_b ), sendMessage $ SetStruts [minBound .. maxBound] [])
    -- Show only upper and left gaps: 
    , (((modMask x .|. controlMask), xK_g              ), sendMessage $ SetStruts [U,L] [minBound .. maxBound])
    -- Hide the bottom keeping whatever the other values were:
    --,  (((modMask x .|. controlMask .|. shiftMask), xK_g), sendMessage $ SetStruts [] [D])
    -- Show only bottom gaps:
    , (((modMask x .|. controlMask .|. shiftMask), xK_g), sendMessage $ SetStruts [D] [minBound .. maxBound])


    -- Jump to layout
    , (((modMask x .|. controlMask .|. shiftMask), xK_j), submap . M.fromList $
      [ 
          -- ((0, xK_t), sendMessage $ JumpToLayout "tiled")
          --,((0, xK_u), sendMessage $ JumpToLayout "full")
          --,((0, xK_f), sendMessage $ JumpToLayout "float")
      ])


    -- Named Scratchpad key
    -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-NamedScratchpad.html
    , (((modMask x .|. controlMask .|. shiftMask), xK_n), submap . M.fromList $
        [ 
          ((0, xK_t), scratchTerm   )
        , ((0, xK_m), scratchMixer  )
        , ((0, xK_v), scratchVideo  )
        , ((0, xK_p), scratchPlayer )
        , ((0, xK_n), scratchMpd    )
        ]
      )
    , ((modMask x, xK_F12), scratchTerm   )
    , ((modMask x, xK_F11), scratchMixer  )
    , ((modMask x, xK_F10), scratchVideo  )
    , ((modMask x, xK_F9 ), scratchPlayer )
    , ((modMask x, xK_F8 ), scratchMpd    )


    -- Popup grid menu for spawning applications
    --, ((modMask x .|. shiftMask, xK_m), spawnSelected defaultGSConfig
    --, ((modMask x .|. shiftMask, xK_m), spawnSelected popupconfig
    --  [
          --"urxvt",
          --"qutebrowser"
        --]
    -- Redefined popup spawnSelected
    , ((modMask x .|. shiftMask, xK_m), spawnSelected'
        [
          ("Ranger"                  , "urxvt -e ranger"   )
        , ("Qute"                    , "qutebrowser"       )
        , ("Mutt"                    , "urxvt -e mutt"     )
        , ("Vivaldi"                 , "vivaldi-stable"    )
        , ("Libreooffice"            , "libreoffice --calc")
        , ("Xterm"                   , "xterm"             )
        , ("TV Library"              , "urxvt -e ranger /media/data01/tv/en/"   )
        , ("Movie Library"           , "urxvt -e ranger /media/data02/movie/ko/")
        , ("TV-Vlc"                  , "vlc ~/tvChannel.xspf"                                   )
        , ("TV-Vapoursynth"          , "mpv --profile tvv $HOME/channels.m3u --playlist-pos 19" )
        , ("TV-Hwdec"                , "mpv --profile tv  $HOME/channels.m3u --playlist-pos 19" )
        , ("Ncmpcpp_tmux"            , "urxvt -title ncmpcpp_tmux -e ~/.ncmpcpp/ncmpcpp_tmux"   )
        , ("XMonad Setting"          , "urxvt -e vi ~/.xmonad/xmonad.hs"                )
        , ("XMobar Left_Top"         , "urxvt -e vi ~/.config/xmobar/xmobarrc-topleft" )
        , ("XMobar Right_Top"        , "urxvt -e vi ~/.config/xmobar/xmobarrc-topright")
        , ("XMobar Bottom"           , "urxvt -e vi ~/.config/xmobar/xmobarrc"         )
        , ("데스크탑 rec-vaapi"      , ".local/bin/record_all_v.sh")
        , ("데스크탑 rec"            , ".local/bin/record_all.sh"  )
        , ("데스크탑 right-rec-vaapi", ".local/bin/record_2_v.sh"  )
        , ("데스크탑 right-rec"      , ".local/bin/record_2.sh"    )
        , ("데스크탑 rec exit"       , ".local/bin/rec_exit.sh"    )
        ]
      )


    -- Computer Power off
    , (((modMask x .|. controlMask .|. shiftMask), xK_Pause), submap . M.fromList $
      [ 
         --((0, xK_s), spawn "dbus-send --system --print-reply --dest='org.freedesktop.UPower' /org/freedesktop/UPower org.freedesktop.UPower.Suspend")                             -- suspend
         ((0, xK_s), spawn "systemctl suspend")     -- suspend
       , ((0, xK_r), spawn "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart") -- Restart
       , ((0, xK_f), spawn "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop")    -- Shutdown
      ]) 

    -- Mornitor on/off
    , (((modMask x .|. controlMask .|. shiftMask), xK_Scroll_Lock), submap . M.fromList $
      [ 
         ((0, xK_a), spawn "xrandr --auto --output HDMI-0 --primary --mode 1920x1080 --left-of DP-5") --  dual mornitor on
       , ((0, xK_l), spawn "xrandr --output HDMI-0 --off"                                           ) --  left mornitor off
       , ((0, xK_r), spawn "xrandr --output DVI-0 --off"                                           ) --  rifht moritor off
       , ((0, xK_o), spawn "xset dpms force suspend"                                              ) --  all monitro off
       , ((0, xK_0), spawn "betterlockscreen -l dim"                                          ) --  screen lock
       --, ((0, xK_0), spawn "xscreensaver-command --lock"                                          ) --  screen lock
      ]) 


    --- Take Screenshot
    -- Full Screenshot : 1. screenshot -dn(delay n sec) then display captured image by "feh -F", 2. fullscreenimage.png is stored to ~/screeenshot/Desktop dir, 3. thumbimage(fullscreenimage's 250x70).png is stored to /screenshot/thumb dir
    -- "scrot -t 6" create fullscreen image and (fullscreen x 6%) thumb image
    , ((0, xK_Print), submap . M.fromList $
      [ 
          ((0, xK_0), spawn "scrot -d 0 -t 250x141 -e 'paplay /usr/share/sounds/freedesktop/stereo/camera-shutter.oga; feh -F *scrot.png && notify-send \"Screenshoot Done\"; mv $f ~/screenshot/desktop; mv *thumb.png ~/screenshot/thumb/'")              -- "PrtSc + 0" keys combinations
       ,  ((0, xK_1), spawn "scrot -d 1 -t 250x141 -e 'paplay /usr/share/sounds/freedesktop/stereo/camera-shutter.oga; feh -F *scrot.png && notify-send \"Screenshoot Done\"; mv $f ~/screenshot/desktop; mv *thumb.png ~/screenshot/thumb/'")              -- "PrtSc + 1" keys combinations
       ,  ((0, xK_5), spawn "scrot -d 5 -t 250x141 -e 'paplay /usr/share/sounds/freedesktop/stereo/camera-shutter.oga; feh -F *scrot.png && notify-send \"Screenshoot Done\"; mv $f ~/screenshot/desktop; mv *thumb.png ~/screenshot/thumb/'")              -- "PrtSc + 5" keys combinations
       ,  ((0, xK_r), spawn "scr r")                                                                              -- "PrtSc + r" keys
       ,  ((0, xK_l), spawn "scr l")                                                                              -- "PrtSc + l" keys
       ,  ((0, xK_a), spawn "scr")                                                                                -- "PrtSc + a" keys
      ]) 
    -- Currently focused window screenshot include grab wm border too
    , ((modMask x                  , xK_Print), spawn "scrot --border -u '%Y-%m-%d-%H%M%S_$wx$h_window.png' -e 'paplay /usr/share/sounds/freedesktop/stereo/camera-shutter.oga; feh -F $f && notify-send \"Screenshoot Done\"; mv $f ~/screenshot/'")       -- "mod + PrtSc" keys combinations
    -- Interactively select a window or rectangle with mouse drag
    , (((modMask x .|. controlMask), xK_Print), spawn "sleep 0.3; scrot -s '%Y-%m-%d-%H%M%S_$wx$h_selection.png' -e 'paplay /usr/share/sounds/freedesktop/stereo/camera-shutter.oga; feh -F $f && notify-send \"Screenshoot Done\"; mv $f ~/screenshot/'")  -- "mod + Control + PrtSc" keys combinations, then mouse drage


    --- PulseAudio Mixer control
    -- Volume up 1%
    --, ((modMask x, xK_KP_Add     ), spawn "amixer -D pulse set Master 2%+ unmute")
    , ((modMask x, xK_KP_Add     ), spawn "~/.xmonad/scripts/volume high")
    -- Volume down -1%
    --, ((modMask x, xK_KP_Subtract), spawn "amixer -D pulse set Master 2%- unmute")
    , ((modMask x, xK_KP_Subtract), spawn "~/.xmonad/scripts/volume low" )
    -- Volume toggle
    --, ((modMask x, xK_KP_Multiply), spawn "amixer -D pulse set Master toggle"    )
    , ((modMask x, xK_KP_Multiply), spawn "~/.xmonad/scripts/volume mute")

    --- Mpd control
    -- Play / pause song in mpd
    ,  (((modMask x .|. shiftMask), xK_p          ), spawn "mpc toggle"   )
    -- Play previous song in mpd
    ,  (((modMask x .|. shiftMask), xK_comma      ), spawn "mpc prev"     )
    -- Play next song in mpd
    ,  (((modMask x .|. shiftMask), xK_period     ), spawn "mpc next"     )
    -- MPD Volume Up
    ,  (((modMask x .|. shiftMask), xK_KP_Add     ), spawn "mpc volume +5")
    -- MPD Volume Down
    ,  (((modMask x .|. shiftMask), xK_KP_Subtract), spawn "mpc volume -5")
    -- random       -- toggle random mode, or specify state
    ,  (((modMask x .|. shiftMask), xK_z          ), spawn "mpc random"   )
    -- single       -- toggle single mode, or specify state
    ,  (((modMask x .|. shiftMask), xK_x          ), spawn "mpc single"   )
    -- consume      -- toggle consume mode, or specify state
    ,  (((modMask x .|. shiftMask), xK_c          ), spawn "mpc consume"  )
    -- repeat       -- toggle repeat mode, or specify state
    ,  (((modMask x .|. shiftMask), xK_v          ), spawn "mpc repeat"   )

    --- Mps-Youtube control
    -- Mpsyt Track info
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Multiply), spawn "~/.xmonad/scripts/mpsytctl trackinfo" )
    -- Mpsyt open web-browser
    , (((modMask x .|. controlMask .|. shiftMask), xK_o          ), spawn "~/.xmonad/scripts/mpsytctl openURL"   )
    -- Mpsyt download video track
    , (((modMask x .|. controlMask .|. shiftMask), xK_u          ), spawn "~/.xmonad/scripts/mpsytctl download"  )
    -- Toggle Play-Pause
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Divide  ), spawn "~/.xmonad/scripts/mpsytctl play-pause")
    -- Play next track
    , (((modMask x .|. controlMask .|. shiftMask), xK_period     ), spawn "~/.xmonad/scripts/mpsytctl next"      )
    -- Play previous track
    , (((modMask x .|. controlMask .|. shiftMask), xK_comma      ), spawn "~/.xmonad/scripts/mpsytctl previous"  )
    -- Mpsyt volume mute 
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Insert  ), spawn "~/.xmonad/scripts/mpsytctl mute"      )
    -- Mpsyt volume up
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Add     ), spawn "~/.xmonad/scripts/mpsytctl volumeUp"  )
    -- Mpsyt volume down
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Subtract), spawn "~/.xmonad/scripts/mpsytctl volumeDown")
    -- Mpsyt volume 10%
    , (((modMask x .|. controlMask .|. shiftMask), xK_1          ), spawn "~/.xmonad/scripts/mpsytctl volume10%" )
    -- Mpsyt volume 20%
    , (((modMask x .|. controlMask .|. shiftMask), xK_2          ), spawn "~/.xmonad/scripts/mpsytctl volume20%" )
    -- Mpsyt volume 30%
    , (((modMask x .|. controlMask .|. shiftMask), xK_3          ), spawn "~/.xmonad/scripts/mpsytctl volume30%" )
    -- Mpsyt volume 40%
    , (((modMask x .|. controlMask .|. shiftMask), xK_4          ), spawn "~/.xmonad/scripts/mpsytctl volume40%" )
    -- Mpsyt volume 50%
    , (((modMask x .|. controlMask .|. shiftMask), xK_5          ), spawn "~/.xmonad/scripts/mpsytctl volume50%" )
    -- Mpsyt volume 60%
    , (((modMask x .|. controlMask .|. shiftMask), xK_6          ), spawn "~/.xmonad/scripts/mpsytctl volume60%" )
    -- Mpsyt volume 70%
    , (((modMask x .|. controlMask .|. shiftMask), xK_7          ), spawn "~/.xmonad/scripts/mpsytctl volume70%" )
    -- Mpsyt volume 80%
    , (((modMask x .|. controlMask .|. shiftMask), xK_8          ), spawn "~/.xmonad/scripts/mpsytctl volume80%" )
    -- Mpsyt volume 90%
    , (((modMask x .|. controlMask .|. shiftMask), xK_9          ), spawn "~/.xmonad/scripts/mpsytctl volume90%" )
    -- Mpsyt volume 100%
    , (((modMask x .|. controlMask .|. shiftMask), xK_0          ), spawn "~/.xmonad/scripts/mpsytctl volume100%")
    -- Mpsyt seek 1 sec forward
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Left    ), spawn "~/.xmonad/scripts/mpsytctl backward"  )
    -- Mpsyt seek 1 sec backward
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Right   ), spawn "~/.xmonad/scripts/mpsytctl forward"   )
    -- Mpsyt seek 10 sec forward
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Up      ), spawn "~/.xmonad/scripts/mpsytctl forward10" )
    -- Mpsyt seek 10 sec backward
    , (((modMask x .|. controlMask .|. shiftMask), xK_KP_Down    ), spawn "~/.xmonad/scripts/mpsytctl backward10")

    --- Exit Mpv
    -- Kill all mpv
    , (((modMask x .|. controlMask .|. shiftMask), xK_v          ), spawn "pkill mpv" )


    -- Exec XBMC
    ,  (((modMask x .|. controlMask), xK_x), spawn "kodi" <+> layoutScreens 1 (fixedLayout [Rectangle 0 0 3840 1080]))
    --,  (((modMask x .|. controlMask), xK_z), spawn "xmbc" <+> withFocused (keysAbsResizeWindow(3840,1080)(0,0)))


    -- Divico remote XF86 key mode
    , ((0, xF86XK_MenuKB), submap . M.fromList $
      [
        ((0, xF86XK_WebCam  ), spawn "xscreensaver-command --lock")     -- screen lock
      , ((0, xF86XK_PowerOff), submap . M.fromList $    --  Computer Power off : XF86 key
        [
          ((0, xK_1), spawn "dbus-send --system --print-reply --dest='org.freedesktop.UPower' /org/freedesktop/UPower org.freedesktop.UPower.Suspend")                             -- suspend
        , ((0, xK_2), spawn "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Restart") -- Restart
        , ((0, xK_3), spawn "dbus-send --system --print-reply --dest='org.freedesktop.ConsoleKit' /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop")    -- Shutdown
        , ((0, xK_0), kill)     -- close focused window
        ])
      , ((0, xK_0), spawn "urxvt -name urxvt-big -fn xft:Hack:bold:pixelsize=44,xft:NanumGothicCoding:bold:pixelsize=48 -fb xft:Hack:bold:pixelsize=44,xft:NanumGothicCoding:bold:pixelsize=48 -e ranger")   -- ranger big font -> workspace 9
      , ((0, xK_1), submap . M.fromList $             -- Mpd Control : XF86 key
        [
        ((0, xK_Cancel  ), spawn "mpc toggle"   )
        , ((0, xK_Left  ), spawn "mpc prev"     )
        , ((0, xK_Right ), spawn "mpc next"     )
        , ((0, xK_Up    ), spawn "mpc volume +5")
        , ((0, xK_Down  ), spawn "mpc volume -5")
        ])
      , ((0, xK_2), spawn "mpv channels.m3u")
      , ((0, xK_3), spawn "killall mpv"     )
      ])

    --- Divico Fusion HDTV7 Remote : exec XBMC , (with lirc config, xbmc mce remote conf)
    ,  ((0, xF86XK_Open         ), spawn "kodi" )
    --,  ((0, xF86XK_Open), spawn "xbmc" <+> layoutScreens 1 (fixedLayout [Rectangle 0 0 3840 1080]))
    -- Toggle Xcinerama layout mode
    ,  ((0, xF86XK_RotateWindows), submap . M.fromList $
        [
        -- Default Layout : "open" + "1" == "ALT-TAB" + "1" (in Fusion remote key)
        ((  0, xK_1), rescreen)
        -- Xcinerama Single layout : "open" + "2" == "ALT-TAB" + "2" (
        , ((0, xK_2), layoutScreens 1 (fixedLayout [Rectangle 0 0 3840 1080]))
        -- Status Bar Toggle Mode : "ALT-TAB" + "0"
        , ((0, xK_0), sendMessage ToggleStruts)
        ])

    ]

    where
        -- this simply means "find the scratchpad in myScratchPads that is 
        -- named terminal and launch it"
        scratchTerm   = namedScratchpadAction myScratchPads "terminal"
        scratchMixer  = namedScratchpadAction myScratchPads "mixer"
        scratchVideo  = namedScratchpadAction myScratchPads "video"
        scratchPlayer = namedScratchpadAction myScratchPads "player"
        scratchMpd    = namedScratchpadAction myScratchPads "mpd"


-- Define keys to remove
keysToRemove x = 
    [
    -- Unused dmenu binding
      (modMask x,               xK_p)
    -- Unused gmrun binding
    , (modMask x .|. shiftMask, xK_p)
    -- Unused close window binding
    , (modMask x .|. shiftMask, xK_c)
    -- Unused xmonad recompile, restart logout binding
    , (modMask x,               xK_q)
    , (modMask x .|. shiftMask, xK_q)
    ]

-- Delete the keys combinations we want to remove
strippedKeys x = foldr M.delete (keys def x) (keysToRemove x)
-- Compose all my new key combinations.
myKeys x       = M.union (strippedKeys x) (M.fromList  (keysToAdd x  ))


----------------------------------------------------------------------------}}}
-- Key bindings. Add, modify or remove key bindings here.                   {{{
-------------------------------------------------------------------------------
inskeys :: XConfig l -> [((KeyMask, KeySym), X ())]
inskeys conf@XConfig {XMonad.modMask = modm} =
    -- Standard Default Keybinding
    --
    -- launch a terminal
    [ ((modm .|. shiftMask, xK_Return), spawn $ XMonad.terminal conf)

    -- launch dmenu
    --, ((modm,               xK_p     ), spawn "dmenu_run")

    -- launch gmrun
    --, ((modm .|. shiftMask, xK_p     ), spawn "gmrun")

    -- 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_comma ), sendMessage (IncMasterN 1))

    -- Deincrement the number of windows in the master area
    , ((modm              , xK_period), sendMessage (IncMasterN (-1)))

    -- Toggle the status bar gap
    -- Use this binding with avoidStruts from Hooks.ManageDocks.
    -- See also the statusBar function from Hooks.DynamicLog.
    --
    --, ((modm              , xK_b     ), sendMessage ToggleStruts)

    -- 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)]]
    -- End of Standard Default Key binding

    -- Set key bindings with customKeys:
    -- unbinding key, full screen toggle
    ++
    --[ ((modm,               xK_p),  spawn "rofi -show drun")     -- redefine x
    [ ((modm,               xK_o),  spawn "rofi -show drun -show-icons")     -- redefine x
    , ((modm .|. shiftMask, xK_o),  spawn "rofi -show run -modi 'run'")
    , ((modm,               xK_i),  spawn "rofi -modi 'clipboard:greenclip print' -show clipboard -font 'Hack bold 8' -lines 20")
    , ((modm,               xK_u),  spawn "rofi -show window -modi 'window'")
    , ((modm,               xK_q),  spawn "")   -- for removing keysToRemove x
    , ((modm .|. shiftMask, xK_q),  spawn "")   -- for removing keysToRemove x
    --for fullscreen toggle, visible border, status
    , ((modm,       xK_Caps_Lock),  sendMessage (XMonad.Layout.ToggleLayouts.Toggle "Full"))
    ]

    ++
    -- XMonad.Layout.BinarySpacePartition Key -- mod1Mask=altMask=Alt_L
    [ ((modm .|. mod1Mask,                  xK_l  ), sendMessage $ ExpandTowards R)
    , ((modm .|. mod1Mask,                  xK_h  ), sendMessage $ ExpandTowards L)
    , ((modm .|. mod1Mask,                  xK_j  ), sendMessage $ ExpandTowards D)
    , ((modm .|. mod1Mask,                  xK_k  ), sendMessage $ ExpandTowards U)
    , ((modm .|. mod1Mask .|. controlMask , xK_l  ), sendMessage $ ShrinkFrom R   )
    , ((modm .|. mod1Mask .|. controlMask , xK_h  ), sendMessage $ ShrinkFrom L   )
    , ((modm .|. mod1Mask .|. controlMask , xK_j  ), sendMessage $ ShrinkFrom D   )
    , ((modm .|. mod1Mask .|. controlMask , xK_k  ), sendMessage $ ShrinkFrom U   )
    , ((modm .|. mod1Mask,                  xK_r  ), sendMessage Rotate           )
    , ((modm .|. mod1Mask,                  xK_s  ), sendMessage Swap             )
    , ((modm .|. mod1Mask,                  xK_n  ), sendMessage FocusParent      )
    , ((modm .|.              controlMask , xK_n  ), sendMessage SelectNode       )
    , ((modm .|.              shiftMask   , xK_n  ), sendMessage MoveNode         )
    , ((modm .|. mod1Mask,                  xK_a  ), sendMessage Balance          )
    , ((modm .|. mod1Mask .|. shiftMask,    xK_a  ), sendMessage Equalize         )
    ]

    ++
    -- Minimize, Maxmize
    [
    -- Makes it possible to minimize windows, temporarily removing them from the
    -- layout until they are restored.
    -- minimize the focused window then focus down 
      --((modm, xK_minus        ), withFocused minimizeWindow)
      ((modm, xK_minus        ), withFocused minimizeWindow <+> windows W.focusDown)

    -- restore the next minimized window. then focus up.
    --, ((modm, xK_equal        ), sendMessage RestoreNextMinimizedWin <+> windows W.focusUp)
    , ((modm, xK_equal        ), withLastMinimized maximizeWindowAndFocus)

    -- Temporarily yanks the focused window out of the layout to mostly fill
    -- the screen : maxmize toggle key.
    , ((modm, xK_backslash    ), withFocused (sendMessage . maximizeRestore))

    -- a simple binding that pushes all floating windows on the current workspace back into tiling
    --, ((modm .|. controlMask .|. shiftMask, xK_t), sinkAll)
    , ((modm .|. controlMask .|. shiftMask, xK_t), sinkAll)
    ]


----------------------------------------------------------------------------}}}
-- Mouse binding: default actions bound to mouse events                     {{{
-------------------------------------------------------------------------------
--
--- Stadard Default mouse keybinding
--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) 
    --]

--- Set custom mouse binding : button8/9 back/forward
--
isFloating :: Window -> X (Bool)
isFloating w = do
    ws <- gets windowset
    return $ M.member w (W.floating ws)

addMouse :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ())
addMouse conf@(XConfig {XMonad.modMask = modMask, XMonad.mouseBindings = defaultBinds}) =
    M.fromList 
    [ -- Movement, only floating mode
      ((modMask, button1), (\w -> Main.isFloating w >>= \isF -> when (isF) $
                                  focus w >> mouseMoveWindow w 
                                          >> windows W.shiftMaster))
    -- Maximize toggle  -- scorll key press
    , ((modMask, button2), (\w -> focus w >> withFocused (sendMessage . maximizeRestore)))
    -- flexible resizing, only floating mode
    , ((modMask, button3), (\w -> Main.isFloating w >>= \isF -> when (isF) $
                                  focus w >> Flex.mouseResizeWindow w 
                                          >> windows W.shiftMaster))
    -- restore the next minimized window. then focus up. -- scroll down
    --, ((modMask, button4), (\w -> focus w >> sendMessage RestoreNextMinimizedWin <+> windows W.focusUp))
    -- Miimize then focus down  -- scroll up
    --, ((modMask, button5), (\w -> focus w >> withFocused minimizeWindow <+> windows W.focusDown))

    -- repeat now with alt/mod1mask: more natural window movements (as in other DE/WMs)
    , ((mod1Mask, button1), \w -> focus w >> mouseMoveWindow w
                                          >> windows W.shiftMaster)
    --
    , ((mod1Mask, button2), windows . (W.shiftMaster .) . W.focusWindow)
    --
    , ((mod1Mask, button3), \w -> focus w >> Flex.mouseResizeWindow w
                                          >> windows W.shiftMaster)
    ]

myMouse layout = addMouse layout `M.union`mouseBindings def layout


----------------------------------------------------------------------------}}}
-- Fade Windows                                                             {{{
-------------------------------------------------------------------------------
-- FadeHook
--
-- need compositer: xcompmgr or compton
-- xcompmgr -cCfF
-- xcompmgr -c -t-5 -l-5 -r4Z.2 -o.55"
myFadeHook = composeAll [isUnfocused --> transparency 0.2
                        ,                opaque
                        ]

----------------------------------------------------------------------------}}}
-- Remove Border Specific Windows                                           {{{
-------------------------------------------------------------------------------
removeBordersEventHook :: Event -> X All
removeBordersEventHook ev = do
--    whenX (className =? "mpv" `runQuery` w) $ withDisplay $ \d ->
--        io $ setWindowBorderWidth d w 0
--    return (All True)
    whenX (className =? "mpv" `runQuery` w) $ withDisplay $ \d -> do
        cw <- io $ wa_border_width <$> getWindowAttributes d w
        unless (cw == 0) $ do
            io $ setWindowBorderWidth d w 0
            refresh
    return (All True)
    where
        w = ev_window ev

----------------------------------------------------------------------------}}}
-- Event handling                                                           {{{
-------------------------------------------------------------------------------
-- * 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 = mempty
--myEventHook = All

-- Note that the event hooks are run left to right (in contrast to
-- -- 'ManageHook'S which are right to left)
myEventHook = mconcat
    [ fadeWindowsEventHook
    , docksEventHook
    , ewmhDesktopsEventHook
    , removeBordersEventHook                           -- always remove border for mpv
    , XMonad.Layout.Fullscreen.fullscreenEventHook       -- mpv "f" key: mpv config value: --x11-netwm=auto, works in floating mode, possible 2 screen full
    --, XMonad.Hooks.EwmhDesktops.fullscreenEventHook    -- mpv "f" key: mpv config value: --x11-netwm=yes,  works in tiling mode, only 1 screen full
    , positionStoreEventHook
    , handleEventHook def ]


----------------------------------------------------------------------------}}}
-- Status bars and logging                                                  {{{
-------------------------------------------------------------------------------
--
-- Workspace Appearance
--
-- Workspace dzen bar (~/.xmonad/lib/[Dzen.hi, Dzen.hs, Dzen.o])
myStatusBar :: DzenConf
myStatusBar = DzenConf {
    x_position    = Just 0               -- 601
    , y_position  = Just 0
    , width       = Just 1920            -- 720 1320 1920
    , Dzen.height = Just 16 
    , alignment   = Just Centered        -- LeftAlign, RightAlign
    , Dzen.font   = Just myDzenFont
    , fg_color    = Just (myColor FG 0)  -- (myColor BG 0)  --312e39
    , bg_color    = Just (myColor BG 0)  -- "#312e39" --"#000000" --33303b
    , exec        = []
    , addargs     = []
}

-- Log Hook:
--
-- Log hook that prints out everything to a dzen handler
-- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html
-- https://github.com/xmonad/xmonadcontrib-reenberg/blob/master/XMonad/Hooks/DynamicLog.hs
-- http://xmonad.org/xmonad-docs/xmonad-contrib/src/XMonad-Util-WorkspaceCompare.html

myLogHook h = dynamicLogWithPP $ myPrettyPrinter h

-- Pretty printer for dzen workspace bar
myPrettyPrinter h = dzenPP {
    --ppCurrent         = dzenColor "#000000" "#e5e5e5"
    ppCurrent           = dzenColor (myColor FG    0) (myColor Magenta 0)  --"#783e57" --"#9144ab"
    , ppVisible         = dzenColor (myColor White 0) (myColor Blue    0)  --"#c0a79a" "#615772" --"#3a3a3a" 
    , ppHidden          = dzenColor (myColor White 0) (myColor Cyan    0)  --"#c0a79a" "#33303b" --"#e5e5e5"
    , ppHiddenNoWindows = dzenColor (myColor BG    0) (myColor BG      0) . \s -> "" --"#312e39" "#312e39" --"#444444" 
    , ppUrgent          = dzenColor (myColor Red   0) (myColor White   0)    --"#312e39". dzenStrip
    , ppSep             = dzenColor (myColor FG    0) (myColor BG      0)  "  "  --" || "
    , ppWsSep           = ""
    , ppTitle           = dzenColor (myColor FG    0) (myColor Magenta 0) . ("  " ++) . dzenEscape . (++ "  ")  --"#783e57"
    , ppLayout          = dzenColor (myColor White 0) (myColor BG    0) . ("  " ++) . dzenEscape . (++ "  ")  --"#c0a79a" "#615772"
    --, ppOrder           = reverse
    --, ppOrder           = \(ws,l,_,xs) -> [l,ws] ++ xs
    --, ppOrder           = \(ws:_:t:_) -> [ws,t]     -- workspace:title,  no layout
    , ppOrder           = \(ws:l:t:_) -> [ws,l,t]                                                                                   -- workspace, layout, title
    , ppSort            = getSortByXineramaRule
    --, ppExtras          = [ padL loadAvg, logCmd "xmonad --version" ]
    , ppOutput          = hPutStrLn h
}


myWsBar :: String
--myWsBar = "~/.cabal/bin/xmobar ~/.config/xmobar/xmobarrc-workspace"
myWsBar = "/usr/bin/xmobar ~/.config/xmobar/xmobarrc-workspace"

myxmobarLogHook j = dynamicLogWithPP . namedScratchpadFilterOutWorkspacePP  $ myWsPrinter j     -- name~filter~PP: not displaying the NSP workspace

-- Pretty printer for xmobar workspace bar
myWsPrinter j = xmobarPP {
    ppCurrent           = xmobarColor (myColor FG    0) (myColor Magenta 0) . wrap  "  ●" ""                                        --"#783e57" "#9144ab"
    , ppVisible         = xmobarColor (myColor White 0) (myColor Red     0) . wrap  "  ♼" ""                                        --"#c0a79a" "#615772" --"#3a3a3a" 
    , ppHidden          = xmobarColor (myColor White 0) (myColor BG      0) . wrap  "  ○" ""                                        --"#c0a79a" "#33303b" --"#e5e5e5"
    , ppHiddenNoWindows = xmobarColor (myColor BG    0) (myColor BG      0) . \s -> ""                                              --"#312e39" "#312e39" --"#444444" 
    , ppUrgent          = xmobarColor (myColor Red   0) (myColor BG      0) . wrap  "  ◌" ""                                        --"#312e39". dzenStrip
    , ppSep             = xmobarColor (myColor FG    0) (myColor BG      0) ""                                                      --" || "
    , ppWsSep           = ""
    , ppTitle           = xmobarColor (myColor FG    0) (myColor Magenta 0) . ("   "   ++) . dzenEscape . (++ "   ") . shorten 94   --"#783e57"
    , ppLayout          = xmobarColor (myColor White 0) (myColor Magenta 0) . ("  ▒ "  ++) . dzenEscape . (++ " ▒" )                --"#c0a79a" "#615772"
    --, ppOrder           = reverse
    --, ppOrder           = \(ws:l:_:xs) -> [l,ws] ++ xs
    --, ppOrder           = \(ws:_:t:_) -> [ws,t]                                                                                   -- workspace:title,  no layout
    , ppOrder           = \(ws:l:t:_) -> [ws,l,t]                                                                                   -- workspace, layout, title
    , ppSort            = getSortByXineramaRule
    --, ppExtras          = [ padL loadAvg, logCmd "xmonad --version" ]
    , ppOutput          = hPutStrLn j
}


----------------------------------------------------------------------------}}}
-- 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.
--
-- By default, do nothing.
--myStartupHook = return ()

-- startup program
myStartupHook :: X()
myStartupHook = do

    -- for java apps 
    --setWMName 'LG3D"

    -- Setting the X cursor
    --spawn "xsetroot -cursor_name RingO"
    spawn "xsetroot -cursor_name left_ptr"

    -- Pulseaudo start
    spawn "systemctl --user start pulseaudio.socket"

    -- cursor disappleance
    --spawn "unclutter -root -idle 5"
    spawn "unclutter -idle 3 -noevents -visible &"

    -- Num Lock key On
    spawn "numlockx on"

    -- Adjust mornitor
    spawn "xrandr --auto --output DP-3 --primary --mode 1920x1080 --left-of DP-5"
    --spawn "xset b off"
    --spawn "xset s off"
    --spawn "xset -dpms"

    -- for qt5 apps's drop-down menu
    --spawn "xprop -root -remove _NET_WORKAREA"

    -- Screen Saver
    --spawn "xscreensaver -no-splash"

    -- xmodemap
    spawn "xmodemap $HOME/.Xmodemap"

    -- Clipboard daemon
    spawn "greenclip daemon"

    -- Fcitx Input method
    spawn "fcitx-autostart"

    -- Load .Xresources
    spawn "xrdb -merge .Xresources"
    spawn "xrdb -merge .Xdefaults"

    -- for vim: to sync the selections
    --spawn "autocutsel -fork"
    --spawn "autocutsel -selection PRIMARY -fork"

    -- Usb Auto Mount
    --spawn "udiskie -q -N -a -t"

    -- Run a Composite manager -- $ xdpyinfo | grep Composite
    -- http://www.haskell.org/haskellwiki/Xmonad/Frequently_asked_questions
    --spawn "xcompmgr -cfF -t-5 -l-5 -r4Z.2 -o.55"
    --spawn "compton --config $HOME/.config/compton/compton.conf"
    spawn "picom --config $HOME/.config/compton/compton.conf"

    -- notify-osd
    spawn "dunst"

    -- Set solid background 
    spawn $ "hsetroot -solid" ++ " \'" ++ (myColor BG 0) ++ "\'"
    --spawn $ "urxvt -e hsetroot -tile $HOME/Pictures/tile.jpg -tint" ++ " \'" ++ (myColor BG 0) ++ "\'"
    -- Background image
    --spawn "sleep 1; $HOME/.fehbg"
    --spawn "feh --no-xinerama --bg-fill ~/Wallpaper/3840x1080_Anime_1382081479862.png"
    --spawn "nitrogen --restore"

    -- Calendar Start (hide, no tray)
    spawn "orage"

    -- Load HP Tray
    spawn "sleep 3; hp-systray"

    -- telegram
    spawn "sleep 3; telegram-desktop"

    -- screenkey
    spawn "sleep 3; screenkey"

    -- caffeine
    spawn "sleep 3; caffeine"

    -- Load Music Player Daemon, then auto start
    spawn "mopidy"
    --spawn "mpd"
    --spawn "sleep 4;ncmpcpp play"
    --spawn "sleep 5; urxvt -name cava_back -e cava"
    --spawn "notification music"


    -- Load Volume-Icon
    --spawn "volumeicon"
    -- Load volnoti daemon
    spawn "volnoti"

    -- Task bar
    spawn "tint2"

    -- mail client
    spawn "sleep 1 && urxvt -e mutt -F $XDG_CONFIG_DIR/mutt/muttrc "
    -- tv channel epg
    spawn "sleep 5 && qutebrowser --backend webengine http://192.168.0.6:9981"

    --nextScreen

    -- mpd, mopidy client
    spawn "(sleep 6); urxvt -e ~/.ncmpcpp/ncmpcpp_tmux"
    spawn "(sleep 8); killall ncmpcpp;  urxvt -title ncmpcpp_tmux -e ~/.ncmpcpp/ncmpcpp_tmux"

    -- Load JTBC NEWS channel play
    spawn "sleep 3; mpv --x11-name mpsyt --fs-screen=all --no-keepaspect --profile tv --playlist-pos 82 channel.m3u"

    -- Load Network mornitering applet
    --spawn "nm-applet"




----------------------------------------------------------------------------}}}
-- Now run xmonad with all the defaults we set up.                          {{{
-------------------------------------------------------------------------------
--
-- Run xmonad with the settings you specify. No need to modify this.
--
--main = xmonad defaults

-- A structure containing your configuration settings, overriding
-- fields in the default config. Any you don't override, will
-- use the defaults defined in xmonad/XMonad/Config.hs
--
-- No need to modify this.
--
--defaults = def {
      -- simple stuff
        --terminal           = myTerminal,
        --focusFollowsMouse  = myFocusFollowsMouse,
        --clickJustFocuses   = myClickJustFocuses,
        --borderWidth        = myBorderWidth,
        --modMask            = myModMask,
        --workspaces         = myWorkspaces,
        --normalBorderColor  = myNormalBorderColor,
        --focusedBorderColor = myFocusedBorderColor,

      -- key bindings
        --keys               = myKeys,
        --mouseBindings      = myMouseBindings,

      -- hooks, layouts
        --layoutHook         = myLayout,
        --manageHook         = myManageHook,
        --handleEventHook    = myEventHook,
        --logHook            = myLogHook,
        --startupHook        = myStartupHook
    --}

defaults = def {
    -- Simple stuff
        terminal             = myTerminal
        , focusFollowsMouse  = myFocusFollowsMouse
        , clickJustFocuses   = myClickJustFocuses
        , borderWidth        = myBorderWidth
        , modMask            = myModMask
        , workspaces         = myWorkspaces
        , normalBorderColor  = myNormalBorderColor
        , focusedBorderColor = myFocusedBorderColor

    -- key bindings
        , keys               = myKeys <+> customKeys (const []) inskeys
        , mouseBindings      = myMouse

    -- hooks, layouts
        , layoutHook         = myLayouts
        , manageHook         = myManageHook
        , handleEventHook    = myEventHook
    }

         `additionalKeysP`
            [
            -- restart xmonad, recompile & restart xmonad
              ("M-S-q"  , spawn "killall xmobar dzen2 trayer hp-systray; xmonad --restart"                      )      -- for trayer icon redraw
            , ("M-C-S-q", spawn "killall xmobar dzen2 trayer screenkey; xmonad --recompile && xmonad --restart")
            --
            -- "M-o" : rofi
            --
            -- dmenu2
            --, ("M-o"  , spawn "x=$(~/.cabal/bin/yeganesh -x -- -i -l 4 -p drun: -fn hack-10 -nb '#312e39' -nf '#c0a79a' -sb '#783e57' -sf '#ffffff') && exec $x")
            , ("M-p"    , spawn $ "x=$(~/.cabal/bin/yeganesh -x -- -i -s 0 -name 'dmenu' -o 1.0 -dim 0 -dc '" -- dim 0.5
                                ++ (myColor Magenta 0)
                                ++ "' -l 0 -h 20 -p '● ♼ ○ ▒ ▒' -fn '" 
                                ++ myDmenuFont 
                                ++ "' -x 500 -y 80 -w 920  -nb '"    -- -y 80 530
                                ++ (myColor Blue    0) 
                                ++ "' -nf '" 
                                ++ (myColor White   0) 
                                ++ "' -sb '" 
                                ++ (myColor Magenta 0) 
                                ++ "' -sf '"
                                ++ (myColor FG      0)
                                ++ "') && exec $x")
            -- dmeu likely launcher
            , ("M-C-p"  ,       prompt ("urxvt" ++ " -e") myPromptConfig)   -- for cli
            , ("M-C-S-p",       runOrRaisePrompt          myPromptConfig)   -- for gui
            --, ("M-S-p",   shellPrompt myPromptConfig)

            --- Toggle Fullscreen, Borders, Mirror
            -- switch to Full (with top.bottom status visible). need avoidstruts
            , ("M-C-<Space>",   sendMessage (XMonad.Layout.ToggleLayouts.Toggle "Full" ))
            -- same to Toggle "Full"
            --, ("M-C-<Space>", sendMessage ToggleLayout)
            -- switch to Full with no borders, no statusbar
            , ("M-f"        ,   sendMessage $ XMonad.Layout.MultiToggle.Toggle NBFULL   )
            -- switch to Full layout, border, no statusbar
            , ("M-C-f"      ,   sendMessage $ XMonad.Layout.MultiToggle.Toggle FULL     )
            -- Remove borders all windows in workspace
            , ("M-C-S-b"    ,   sendMessage $ XMonad.Layout.MultiToggle.Toggle NOBORDERS)
            -- Toggle the border of the currently focused window
            , ("M-C-b"      ,   withFocused toggleBorder                                )
            -- he Mirror transformation:
            , ("M-C-S-m"    ,   sendMessage $ XMonad.Layout.MultiToggle.Toggle MIRROR   )   -- bottom xmobar toggle struct. then properly works.

            -- Background images
            --, ("M-`"    , spawn "urxvt -e $HOME/.fehbg; mpc volume +1; sleep 1; mpc volume -1")
            , ("M-`"    , spawn "$HOME/.fehbg;")
            --, ("M-S-`"  , spawn $ "urxvt -e hsetroot -solid" ++ " \'" ++ (myColor BG 0) ++ "\'; mpc volume +1; sleep 1; mpc volume -1")
            --, ("M-S-`"  , spawn $ "urxvt -e hsetroot -solid" ++ " \'" ++ (myColor BG 0) ++ "\'")
            --, ("M-S-`"  , spawn $ "urxvt -e hsetroot -tile $HOME/Pictures/tile.jpg -tint" ++ " \'" ++ (myColor BG 0) ++ "\'")
            , ("M-S-`"  , spawn $ "hsetroot -solid" ++ " \'" ++ (myColor BG 0) ++ "\'")

            -- show messege of default xmonad keybindings 
            , ("M-S-/"  , spawn ("echo \"" ++ help ++ "\" | gxmessage -geometry 900x700 -font monospace -file -"))

            --, ("<XF86Open>"            , spawn "kodi")
            --, ("<XF86AudioRaiseVolume>", spawn "amixer set Master 1%+")
            --, ("<XF86AudioLowerVolume>", spawn "amixer set Master 1%-")
            --, ("<XF86AudioMute>"       , spawn "amixer set Master toggle")
            -- Media Keys
            --, ("0x1008ff12" , spawn "vol mute") -- XF86AudioMute
            --, ("0x1008ff11" , spawn "vol down") -- XF86AudioLowerVolume
            --, ("0x1008ff13" , spawn "vol up")   -- XF86AudioRaiseVolume
            ]



main :: IO ()
main = do
    wsxmobar     <- spawnPipe myWsBar                   -- workspace xmobar bar
    --wsdzenbar    <- spawnDzen myStatusBar             -- workspace dzen bar

    --xmproc       <- spawnPipe "~/.cabal/bin/xmobar"     -- bottom monitoring xmobar 
    xmproc       <- spawnPipe "/usr/bin/xmobar ~/.config/xmobar/xmobarrc"     -- bottom monitoring xmobar 

    spawn "sleep 3; trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --widthtype request --width 10 --transparent true --alpha 255 --tint 0x312e39 --height 16 --distancefrom right --distance 440"    -- transparent: alpha 255, --distancefrom right --distance 121" 

    --spawn "sleep 4; xfce4-panel"

    args <- getArgs

    --when ("--replace" `elem` args) replace


    xmonad $ withUrgencyHook NoUrgencyHook $ ewmh defaults {
    -- logHook
        logHook       = composeAll
            [
            fadeWindowsLogHook myFadeHook
            , myxmobarLogHook wsxmobar                            -- workspace status xmobar
            --, myLogHook wsdzenbar                               -- workspace status dzenbar
            , ewmhDesktopsLogHook
            , logHook def >> updatePointer (0.5, 0.5) (0.5, 0.5)                -- moves pointer to center of focused window
            -- >> updatePointer (0.99, 0.99) (0.5, 0.5)                -- moves pointer to center of focused window
            ]
    -- startupHook
        --, startupHook      = myStartupHook >> setWMName "LG3D"
        --, startupHook = when (null args) $ myStartupHook >> setWMName "LG3D"          -- when args is "--restart", is not executed startupHook
        , startupHook = when (null args) $ myStartupHook >> setWMName "XMonad"        -- when args is "--restart", is not executed startupHook
    }

----------------------------------------------------------------------------}}}
-- Help                                                                     {{{
-------------------------------------------------------------------------------
--
-- | Finally, a copy of the default bindings in simple textual tabular format.
-- help key : mode4mask + ?    -- $ pacman -S xorg-xmessage gxmessage
help :: String
help = unlines 
    [ "Default Standard Keybindings:"
    , ""
    , "The default modifier key is 'mod4mask'=='window key'"
    , ""
    , "-- launching and killing programs"
    , "mod-shft-Enter        Launch xterminal"
    , "mod-p                 (Launch dmenu) --> Launch dmenu2"
    , "mod-shft-p            (Launch gmrun) --> Launch mpd toggle"
    , "(mod-shft-c)          Close/kill the focused window, but not copies"
    , " --> mod-c"
    , "mod-Space             Rotate through the available layout algorithms"
    , "mod-shft-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-shft-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-shft-j            Swap the focused window with the next window"
    , "mod-shft-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-shft-q            (Quit xmonad)    --> restart xmonad"
    , "mod-q                 (Restart xmonad) --> key disable"
    , "mod-control-shift-q   Restart xmonad   --> recompile & restart xmoand"
    , ""
    , "-- Workspaces & screens"
    , "mod-[1..0]            Switch to workSpace N"
    , "mod-shft-[1..0]       Move client to workspace N"
    , "mod-{w,e,r}           Switch to physical/Xinerama screens 1, 2, or 3"
    , "mod-shft-{w,e,r}      Move client to screen 1, 2, or 3"
    , ""
    , "-- Mouse bindings: default actions bound to mouse events (mod --> mod1mask)"
    , "mod1-button1           Set the window to floating mode and move by dragging"
    , "mod1-button2           Raise the window to the top of the stack"
    , "mod1-button3           Set the window to floating mode and resize by dragging"
    ]
----------------------------------------------------------------------------}}}
-- vim: ft=haskell:foldmethod=marker:foldlevel=0:ts=4:sw=4
 

* Cycle layout 

 

 

* Bsp(BinarySpaceParition) layout + Nsp(NamedScratchPad)

 

* ThreeColumns layout

 

 

 

* (previous setting) xmonad 0.12 in ubuntu
Linux Desktop Minimal Setting

 


 

* (current setting) xmonad 0.13 in arch : https://imgur.com/a/UsRcv
Arch Linux Desktop Screenshot