diff --git a/dotfiles/config/xmonad/base.nix b/dotfiles/config/xmonad/base.nix new file mode 100644 index 00000000..f90655da --- /dev/null +++ b/dotfiles/config/xmonad/base.nix @@ -0,0 +1,6 @@ +(import ../taffybar/taffybar/nixpkgs.nix) { + overlays = [ + (import ../taffybar/taffybar/overlay.nix) + (import ./overlay.nix) + ]; +} diff --git a/dotfiles/config/xmonad/build b/dotfiles/config/xmonad/build index e0dc98aa..a0f68d10 100755 --- a/dotfiles/config/xmonad/build +++ b/dotfiles/config/xmonad/build @@ -7,5 +7,4 @@ output_file=$1; shift cd "$SRC_DIR" exe_location="$SRC_DIR/result/bin/imalison-xmonad" nix-build -echo "$exe_location" "$output_file" > did_build cp -f "$exe_location" "$output_file" diff --git a/dotfiles/config/xmonad/cabal.project b/dotfiles/config/xmonad/cabal.project new file mode 100644 index 00000000..e6fdbadb --- /dev/null +++ b/dotfiles/config/xmonad/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/dotfiles/config/xmonad/default.nix b/dotfiles/config/xmonad/default.nix index bd64f85a..b70d636a 100644 --- a/dotfiles/config/xmonad/default.nix +++ b/dotfiles/config/xmonad/default.nix @@ -1,6 +1 @@ -let - pkgs = import { overlays = [ (import ./overlay.nix) ]; }; - source = pkgs.lib.sourceByRegex ./. [ - "xmonad.hs" "imalison-xmonad.cabal" "PagerHints.hs" "LICENSE" - ]; -in pkgs.haskellPackages.callCabal2nix "imalison-xmonad" source { } +(import ./base.nix).haskellPackages.imalison-xmonad diff --git a/dotfiles/config/xmonad/imalison-xmonad.cabal b/dotfiles/config/xmonad/imalison-xmonad.cabal index 29cd7a81..b7eb3bc4 100644 --- a/dotfiles/config/xmonad/imalison-xmonad.cabal +++ b/dotfiles/config/xmonad/imalison-xmonad.cabal @@ -23,11 +23,12 @@ executable imalison-xmonad , multimap>=1.2.1 , process>=1.4.3.0 , split + , taffybar , transformers>=0.5.2.0 , tuple >= 0.3.0.2 , utf8-string - , xmonad-contrib>=0.13 - , xmonad>=0.13 + , xmonad-contrib + , xmonad hs-source-dirs: . other-modules: PagerHints default-language: Haskell2010 diff --git a/dotfiles/config/xmonad/overlay.nix b/dotfiles/config/xmonad/overlay.nix index 75d46de7..edd72ee8 100644 --- a/dotfiles/config/xmonad/overlay.nix +++ b/dotfiles/config/xmonad/overlay.nix @@ -3,6 +3,13 @@ _: pkgs: rec { overrides = pkgs.lib.composeExtensions (old.overrides or (_: _: {})) (self: super: rec { xmonad = self.callCabal2nix "xmonad" (fetchGit ./xmonad) { }; xmonad-contrib = self.callCabal2nix "xmonad-contrib" (fetchGit ./xmonad-contrib) { }; + imalison-xmonad = self.callCabal2nix "imalison-xmonad" ( + pkgs.lib.sourceByRegex ./. + [ + "xmonad.hs" "imalison-xmonad.cabal" + "PagerHints.hs" "LICENSE" + ] + ) { }; }); }); } diff --git a/dotfiles/config/xmonad/shell.nix b/dotfiles/config/xmonad/shell.nix new file mode 100644 index 00000000..fc948675 --- /dev/null +++ b/dotfiles/config/xmonad/shell.nix @@ -0,0 +1,3 @@ +let + pkgs = (import ./base.nix); +in pkgs.haskellPackages.shellFor { packages = p: [ p.imalison-xmonad ]; } diff --git a/dotfiles/config/xmonad/xmonad.hs b/dotfiles/config/xmonad/xmonad.hs index 093d4bc1..94be0bb6 100644 --- a/dotfiles/config/xmonad/xmonad.hs +++ b/dotfiles/config/xmonad/xmonad.hs @@ -10,6 +10,8 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.Maybe import Data.Aeson import qualified Data.ByteString.Lazy as B +import Data.Char +import Data.Foldable import Data.List import Data.List.Split import qualified Data.Map as M @@ -24,7 +26,10 @@ import Network.HostName import PagerHints import System.Directory import System.FilePath.Posix +import System.IO.Unsafe import System.Process +import System.Taffybar.Hooks +import System.Taffybar.Information.XDG.DesktopEntry import Text.Printf import Unsafe.Coerce import XMonad hiding ( (|||) ) @@ -173,7 +178,7 @@ followingWindow action = do whenJust orig $ windows . W.focusWindow return res -myDmenuArgs = ["-dmenu", "-i"] +myDmenuArgs = ["-dmenu", "-i", "-show-icons"] myDmenu = DM.menuArgs "rofi" myDmenuArgs @@ -330,7 +335,7 @@ deactivateFullAnd action = sequence_ [deactivateFull, action] andDeactivateFull action = sequence_ [action, deactivateFull] -goFullscreen = sendMessage $ Toggle NBFULL +goFullscreen = sendMessage $ JumpToLayout "Tabbed Simplest" -- Layout setup @@ -389,17 +394,31 @@ getVirtualClass = flip findM virtualClasses . classIfMatches getClass w = fromMaybe <$> getClassRaw w <*> getVirtualClass w +desktopEntriesMap :: MM.MultiMap String DesktopEntry +desktopEntriesMap = + unsafePerformIO $ do + tee id (>>= writeToHomeDirLog . show . MM.keys) $ + directoryEntriesByClassName <$> getDirectoryEntriesDefault + +lookupIconFromClasses classes = + getFirst $ fold $ First . deIcon <$> (classes >>= idAndLower >>= flip MM.lookup desktopEntriesMap) + where idAndLower value = [value, map toLower value] + myDecorateName ws w = do name <- show <$> getName w + rawClass <- getClassRaw w classTitle <- getClass w workspaceToName <- getWorkspaceNames - return $ printf "%-20s%-40s %+30s" classTitle (take 40 name) - "in " ++ workspaceToName (W.tag ws) + let iconName = fromMaybe "" $ lookupIconFromClasses [rawClass, classTitle] + entryString = printf "%-20s%-40s %+30s in %s \0icon\x1f%s" + classTitle (take 40 name) " " (workspaceToName (W.tag ws)) iconName + return entryString -data ChromeInfo = ChromeInfo { tabId :: Int - , tabUri :: String - , tabTitle :: String - } deriving (Eq, Show) +data ChromeInfo = ChromeInfo + { tabId :: Int + , tabUri :: String + , tabTitle :: String + } deriving (Eq, Show) getChromeTabInfo = do output <- runProcessWithInput "chromix-too" ["ls"] "" @@ -434,10 +453,10 @@ chromeTabAction doSplit action selected = -- This needs access to X in order to unminimize, which means that it can't be -- done with the existing window bringer interface -myWindowAct c@WindowBringerConfig {menuCommand = cmd, menuArgs = args} filterVisible action = do +myWindowAct c@WindowBringerConfig {menuCommand = cmd, menuArgs = args} + filterVisible action = do visible <- visibleWindows currentlyFullscreen <- isToggleActiveInCurrent NBFULL - -- Uncomment filter to remove windows that are visible let actualConfig = if fromMaybe False currentlyFullscreen then c @@ -446,7 +465,6 @@ myWindowAct c@WindowBringerConfig {menuCommand = cmd, menuArgs = args} filterVis then c {windowFilter = not . flip elem visible} else c ws <- windowMap' actualConfig - -- chromeTabs <- liftIO getChromeTabInfo let options = M.union (M.map Left ws) (M.map Right M.empty) selection <- DM.menuMapArgs cmd args options whenJust selection action