taffybar: use submodule and improve hyprland config
This commit is contained in:
40
dotfiles/config/taffybar/flake.lock
generated
40
dotfiles/config/taffybar/flake.lock
generated
@@ -115,11 +115,11 @@
|
||||
"gtk-sni-tray": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1760550917,
|
||||
"narHash": "sha256-oELopLiVb7D1fzYHAiw/cbfNPHLQcOJ3Rz/I1gbk8IY=",
|
||||
"lastModified": 1770069502,
|
||||
"narHash": "sha256-jreuryLGfbyNwx5yEtOYGt2PX+uyGRsgmakYfCQ+OdM=",
|
||||
"owner": "taffybar",
|
||||
"repo": "gtk-sni-tray",
|
||||
"rev": "f6d1bf5dd64ac0f532b03ae01f5e1cc051116f09",
|
||||
"rev": "733a43f187b35bf65b443a7ede70d62f684932ef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -148,16 +148,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1764252443,
|
||||
"narHash": "sha256-U4G4dUSYWZYKtrF7/ozebD1B96at08SIhY4R9OaK1nw=",
|
||||
"owner": "colonelpanic8",
|
||||
"lastModified": 1770181073,
|
||||
"narHash": "sha256-ksTL7P9QC1WfZasNlaAdLOzqD8x5EPyods69YBqxSfk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e1fc6c25b91d3d49dd02a156237721f12dbd86b2",
|
||||
"rev": "bf922a59c5c9998a6584645f7d0de689512e444c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "colonelpanic8",
|
||||
"ref": "remove-gi-gtk-hs-patch",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -310,18 +310,14 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1760591109,
|
||||
"narHash": "sha256-O21ayp5v2eccXdcwNjTK5ZB99ruK0Zt9CUaw5Rye42g=",
|
||||
"owner": "taffybar",
|
||||
"repo": "taffybar",
|
||||
"rev": "b256a711416036ca124fc9b3f89e7c957535e465",
|
||||
"type": "github"
|
||||
"lastModified": 1770273353,
|
||||
"narHash": "sha256-0VQfT0bxyU+xmEMLDRQq+hbJX35+PWPjSXiAVFGOlzQ=",
|
||||
"path": "/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"owner": "taffybar",
|
||||
"ref": "master",
|
||||
"repo": "taffybar",
|
||||
"type": "github"
|
||||
"path": "/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar",
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
"unstable": {
|
||||
@@ -349,11 +345,11 @@
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1748252779,
|
||||
"narHash": "sha256-kSyD/VDUX2m9c2vcuLBT2wnpYiVSHHlP9vuDTtsAtD8=",
|
||||
"lastModified": 1764753633,
|
||||
"narHash": "sha256-6552zbHzdNnkREnOluE6xePIib5cc/8Nc5OnPyHORUo=",
|
||||
"owner": "NorfairKing",
|
||||
"repo": "weeder-nix",
|
||||
"rev": "388df7a6f00220d1960118e1ad37cd86150d2c5a",
|
||||
"rev": "2203c43ab9f1c4e52c2cff8e3d01bbb53159b922",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
nixpkgs.url = "github:colonelpanic8/nixpkgs/remove-gi-gtk-hs-patch";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
xmonad.url = "github:xmonad/xmonad/master";
|
||||
taffybar = {
|
||||
url = "github:taffybar/taffybar/master";
|
||||
url = "path:/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.xmonad.follows = "xmonad";
|
||||
};
|
||||
@@ -16,7 +16,7 @@
|
||||
taffybar = prev.haskell.lib.overrideCabal hsuper.taffybar (oa: {
|
||||
doHaddock = false;
|
||||
doCheck = false;
|
||||
# Fix for GHC 9.4 where liftA2 is not in Prelude
|
||||
# Legacy fix for older GHC (harmless on newer)
|
||||
postPatch = (oa.postPatch or "") + ''
|
||||
substituteInPlace src/System/Taffybar/DBus/Client/Util.hs \
|
||||
--replace-fail "import Control.Monad (forM)" \
|
||||
@@ -47,7 +47,7 @@ import Control.Applicative (liftA2)"
|
||||
final.xorg.libXtst.out
|
||||
];
|
||||
};
|
||||
defComp = { compiler = "ghc94"; };
|
||||
defComp = { compiler = "ghc98"; };
|
||||
overlay = xmonad.lib.fromHOL hoverlay defComp;
|
||||
overlayList = [ taffybar.overlays.default overlay ];
|
||||
in flake-utils.lib.eachDefaultSystem (system:
|
||||
@@ -57,10 +57,21 @@ import Control.Applicative (liftA2)"
|
||||
{
|
||||
devShell = hpkgs.shellFor {
|
||||
packages = p: [ p.imalison-taffybar p.taffybar ];
|
||||
nativeBuildInputs = with hpkgs; [
|
||||
nativeBuildInputs = (with hpkgs; [
|
||||
cabal-install
|
||||
# ghcid ormolu implicit-hie haskell-language-server hlint
|
||||
]) ++ [
|
||||
pkgs.gdk-pixbuf
|
||||
pkgs.librsvg
|
||||
];
|
||||
shellHook = ''
|
||||
if [ -z "''${GDK_PIXBUF_MODULE_FILE:-}" ]; then
|
||||
export GDK_PIXBUF_MODULE_FILE="${pkgs.gdk-pixbuf}/lib/gdk-pixbuf-2.0/${pkgs.gdk-pixbuf.version}/loaders.cache"
|
||||
fi
|
||||
if [ -z "''${GDK_PIXBUF_MODULEDIR:-}" ]; then
|
||||
export GDK_PIXBUF_MODULEDIR="${pkgs.gdk-pixbuf}/lib/gdk-pixbuf-2.0/${pkgs.gdk-pixbuf.version}/loaders"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
defaultPackage = hpkgs.imalison-taffybar;
|
||||
}) // {
|
||||
|
||||
@@ -22,6 +22,7 @@ executable taffybar
|
||||
, directory
|
||||
, filepath
|
||||
, gi-gtk3
|
||||
, gi-gdkpixbuf
|
||||
, gtk-sni-tray
|
||||
, gtk-strut
|
||||
, haskell-gi-base
|
||||
|
||||
Submodule dotfiles/config/taffybar/taffybar updated: 220cb5a34d...05d7a1f8fa
@@ -15,6 +15,7 @@ import qualified Data.Map as M
|
||||
import Data.Maybe
|
||||
import qualified Data.Text
|
||||
import Data.Time
|
||||
import qualified GI.GdkPixbuf.Objects.Pixbuf as Gdk
|
||||
import qualified GI.Gtk as Gtk
|
||||
import qualified GI.Gtk.Objects.Overlay as Gtk
|
||||
import Network.HostName
|
||||
@@ -28,7 +29,7 @@ import System.Log.Handler.Simple
|
||||
import System.Log.Logger
|
||||
import System.Process
|
||||
import System.Taffybar
|
||||
import System.Taffybar.Context (appendHook)
|
||||
import System.Taffybar.Context (Backend(..), TaffyIO, appendHook, detectBackend)
|
||||
import System.Taffybar.DBus
|
||||
import System.Taffybar.DBus.Toggle
|
||||
import System.Taffybar.Hooks
|
||||
@@ -43,9 +44,12 @@ import System.Taffybar.Widget.Generic.Icon
|
||||
import System.Taffybar.Widget.Generic.PollingGraph
|
||||
import System.Taffybar.Widget.Generic.PollingLabel
|
||||
import System.Taffybar.Widget.Util
|
||||
import System.Taffybar.Widget.Workspaces
|
||||
import qualified System.Taffybar.Widget.HyprlandWorkspaces as Hyprland
|
||||
import qualified System.Taffybar.Widget.Workspaces as X11Workspaces
|
||||
import System.Taffybar.WindowIcon (pixBufFromColor)
|
||||
import Text.Printf
|
||||
import Text.Read hiding (lift)
|
||||
import Data.Int (Int32)
|
||||
|
||||
setClassAndBoundingBoxes :: MonadIO m => Data.Text.Text -> Gtk.Widget -> m Gtk.Widget
|
||||
setClassAndBoundingBoxes klass = buildContentsBox >=> flip widgetSetClassGI klass
|
||||
@@ -97,7 +101,7 @@ getFullWorkspaceNames = go <$> readAsListOfString Nothing "_NET_DESKTOP_FULL_NAM
|
||||
where go = zip [WorkspaceId i | i <- [0..]]
|
||||
|
||||
workspaceNamesLabelSetter workspace =
|
||||
remapNSP . fromMaybe "" . lookup (workspaceIdx workspace) <$>
|
||||
remapNSP . fromMaybe "" . lookup (X11Workspaces.workspaceIdx workspace) <$>
|
||||
liftX11Def [] getFullWorkspaceNames
|
||||
where remapNSP "NSP" = "S"
|
||||
remapNSP n = n
|
||||
@@ -124,6 +128,106 @@ logDebug = do
|
||||
-- enableLogger "System.Taffybar.WindowIcon" DEBUG
|
||||
-- enableLogger "System.Taffybar.Widget.Generic.PollingLabel" DEBUG
|
||||
|
||||
iconRemap :: [(Data.Text.Text, [Data.Text.Text])]
|
||||
iconRemap =
|
||||
[ ("spotify", ["spotify-client", "spotify"])
|
||||
]
|
||||
|
||||
iconRemapMap :: M.Map Data.Text.Text [Data.Text.Text]
|
||||
iconRemapMap =
|
||||
M.fromList [ (Data.Text.toLower k, v) | (k, v) <- iconRemap ]
|
||||
|
||||
lookupIconRemap :: Data.Text.Text -> [Data.Text.Text]
|
||||
lookupIconRemap name = fromMaybe [] $ M.lookup (Data.Text.toLower name) iconRemapMap
|
||||
|
||||
iconNameVariants :: Data.Text.Text -> [Data.Text.Text]
|
||||
iconNameVariants raw =
|
||||
let lower = Data.Text.toLower raw
|
||||
stripped = fromMaybe lower (Data.Text.stripSuffix ".desktop" lower)
|
||||
suffixes = ["-gtk", "-client", "-desktop"]
|
||||
stripSuffixes name =
|
||||
let variants = mapMaybe (`Data.Text.stripSuffix` name) suffixes
|
||||
in nub $ variants ++ [name]
|
||||
baseNames = stripSuffixes stripped ++ [raw]
|
||||
toDash c
|
||||
| c == ' ' || c == '_' || c == '.' || c == '/' = '-'
|
||||
| otherwise = c
|
||||
toUnderscore c
|
||||
| c == ' ' || c == '-' || c == '.' || c == '/' = '_'
|
||||
| otherwise = c
|
||||
variantsFor name =
|
||||
let dotted =
|
||||
case Data.Text.splitOn "." name of
|
||||
[] -> name
|
||||
xs -> last xs
|
||||
dashed = Data.Text.map toDash name
|
||||
dashedDotted = Data.Text.map toDash dotted
|
||||
underscored = Data.Text.map toUnderscore name
|
||||
underscoredDotted = Data.Text.map toUnderscore dotted
|
||||
in [dotted, dashed, dashedDotted, underscored, underscoredDotted, name]
|
||||
in nub $ concatMap variantsFor baseNames
|
||||
|
||||
isSpecialHyprWorkspace :: Hyprland.HyprlandWorkspace -> Bool
|
||||
isSpecialHyprWorkspace ws =
|
||||
let name = Data.Text.toLower $ Data.Text.pack $ Hyprland.workspaceName ws
|
||||
in Data.Text.isPrefixOf "special" name || Hyprland.workspaceIdx ws < 0
|
||||
|
||||
hyprlandIconCandidates :: Hyprland.HyprlandWindow -> [Data.Text.Text]
|
||||
hyprlandIconCandidates windowData =
|
||||
let baseNames = map Data.Text.pack $ catMaybes
|
||||
[ Hyprland.windowClass windowData
|
||||
, Hyprland.windowInitialClass windowData
|
||||
]
|
||||
remapped = concatMap lookupIconRemap baseNames
|
||||
remappedExpanded = concatMap iconNameVariants remapped
|
||||
baseExpanded = concatMap iconNameVariants baseNames
|
||||
in nub (remappedExpanded ++ baseExpanded)
|
||||
|
||||
isPathCandidate :: Data.Text.Text -> Bool
|
||||
isPathCandidate name =
|
||||
Data.Text.isInfixOf "/" name ||
|
||||
any (`Data.Text.isSuffixOf` name) [".png", ".svg", ".xpm"]
|
||||
|
||||
hyprlandIconFromCandidate size name
|
||||
| isPathCandidate name =
|
||||
liftIO $ getPixbufFromFilePath (Data.Text.unpack name)
|
||||
| otherwise =
|
||||
maybeTCombine
|
||||
(Hyprland.getWindowIconFromDesktopEntryByAppId size (Data.Text.unpack name))
|
||||
(liftIO $ loadPixbufByName size name)
|
||||
|
||||
hyprlandManualIconGetter :: Hyprland.HyprlandWindowIconPixbufGetter
|
||||
hyprlandManualIconGetter =
|
||||
Hyprland.handleIconGetterException $ \size windowData ->
|
||||
foldl maybeTCombine (return Nothing) $
|
||||
map (hyprlandIconFromCandidate size) (hyprlandIconCandidates windowData)
|
||||
|
||||
fallbackIconPixbuf :: Int32 -> TaffyIO (Maybe Gdk.Pixbuf)
|
||||
fallbackIconPixbuf size = do
|
||||
let fallbackNames =
|
||||
[ "application-x-executable"
|
||||
, "application"
|
||||
, "image-missing"
|
||||
, "gtk-missing-image"
|
||||
, "dialog-question"
|
||||
, "utilities-terminal"
|
||||
, "system-run"
|
||||
, "window"
|
||||
]
|
||||
tryNames =
|
||||
foldl
|
||||
maybeTCombine
|
||||
(return Nothing)
|
||||
(map (liftIO . loadPixbufByName size) fallbackNames)
|
||||
result <- tryNames
|
||||
case result of
|
||||
Just _ -> return result
|
||||
Nothing -> Just <$> pixBufFromColor size 0x5f5f5fff
|
||||
|
||||
hyprlandFallbackIcon :: Hyprland.HyprlandWindowIconPixbufGetter
|
||||
hyprlandFallbackIcon size _ =
|
||||
fallbackIconPixbuf size
|
||||
|
||||
cssFilesByHostname =
|
||||
[ ("uber-loaner", ["uber-loaner.css"])
|
||||
, ("imalison-home", ["taffybar.css"])
|
||||
@@ -136,7 +240,7 @@ main = do
|
||||
enableLogger "Graphics.UI.GIGtkStrut" DEBUG
|
||||
|
||||
hostName <- getHostName
|
||||
homeDirectory <- getHomeDirectory
|
||||
backend <- detectBackend
|
||||
let relativeFiles = fromMaybe ["taffybar.css"] $ lookup hostName cssFilesByHostname
|
||||
cssFiles <- mapM (getUserConfigFile "taffybar") relativeFiles
|
||||
|
||||
@@ -152,19 +256,31 @@ main = do
|
||||
windowsNew defaultWindowsConfig
|
||||
myWorkspaces =
|
||||
flip widgetSetClassGI "workspaces" =<<
|
||||
workspacesNew defaultWorkspacesConfig
|
||||
X11Workspaces.workspacesNew X11Workspaces.defaultWorkspacesConfig
|
||||
{ minIcons = 1
|
||||
, getWindowIconPixbuf =
|
||||
scaledWindowIconPixbufGetter $
|
||||
getWindowIconPixbufFromChrome <|||>
|
||||
unscaledDefaultGetWindowIconPixbuf <|||>
|
||||
(\size _ -> lift $ loadPixbufByName size
|
||||
"application-default-icon")
|
||||
X11Workspaces.scaledWindowIconPixbufGetter $
|
||||
X11Workspaces.getWindowIconPixbufFromChrome <|||>
|
||||
X11Workspaces.unscaledDefaultGetWindowIconPixbuf <|||>
|
||||
(\size _ -> fallbackIconPixbuf size)
|
||||
, widgetGap = 0
|
||||
, showWorkspaceFn = hideEmpty
|
||||
, showWorkspaceFn = X11Workspaces.hideEmpty
|
||||
, updateRateLimitMicroseconds = 100000
|
||||
, labelSetter = workspaceNamesLabelSetter
|
||||
, widgetBuilder = buildLabelOverlayController
|
||||
, widgetBuilder = X11Workspaces.buildLabelOverlayController
|
||||
}
|
||||
myHyprWorkspaces =
|
||||
flip widgetSetClassGI "workspaces" =<<
|
||||
Hyprland.hyprlandWorkspacesNew Hyprland.defaultHyprlandWorkspacesConfig
|
||||
{ Hyprland.widgetGap = 0
|
||||
, Hyprland.minIcons = 1
|
||||
, Hyprland.showWorkspaceFn =
|
||||
(\ws -> Hyprland.workspaceState ws /= Hyprland.Empty &&
|
||||
not (isSpecialHyprWorkspace ws))
|
||||
, Hyprland.getWindowIconPixbuf =
|
||||
hyprlandManualIconGetter <|||>
|
||||
Hyprland.defaultHyprlandGetWindowIconPixbuf <|||>
|
||||
hyprlandFallbackIcon
|
||||
}
|
||||
myClock = deocrateWithSetClassAndBoxes "clock" $
|
||||
textClockNewWith
|
||||
@@ -193,7 +309,7 @@ main = do
|
||||
]
|
||||
fullEndWidgets = baseEndWidgets ++ [ myCPU, myMem, myNet, myMpris ]
|
||||
laptopEndWidgets = batteryWidgets ++ baseEndWidgets
|
||||
baseConfig =
|
||||
baseConfigX11 =
|
||||
defaultSimpleTaffyConfig
|
||||
{ startWidgets = [ myWorkspaces, myLayout, myWindows ]
|
||||
, endWidgets = baseEndWidgets
|
||||
@@ -204,30 +320,65 @@ main = do
|
||||
, cssPaths = cssFiles
|
||||
, centerWidgets = [ myClock ]
|
||||
}
|
||||
selectedConfig =
|
||||
fromMaybe baseConfig $ lookup hostName
|
||||
baseConfigWayland =
|
||||
defaultSimpleTaffyConfig
|
||||
{ startWidgets = [ myHyprWorkspaces ]
|
||||
, endWidgets = baseEndWidgets
|
||||
, barPosition = Top
|
||||
, widgetSpacing = 0
|
||||
, barPadding = 0
|
||||
, barHeight = ScreenRatio $ 1/27
|
||||
, cssPaths = cssFiles
|
||||
, centerWidgets = [ myClock ]
|
||||
}
|
||||
x11Overrides =
|
||||
[ ( "uber-loaner"
|
||||
, baseConfig { endWidgets = laptopEndWidgets }
|
||||
, baseConfigX11 { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "adell"
|
||||
, baseConfig { endWidgets = laptopEndWidgets }
|
||||
, baseConfigX11 { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "stevie-nixos"
|
||||
, baseConfig { endWidgets = laptopEndWidgets
|
||||
, baseConfigX11 { endWidgets = laptopEndWidgets
|
||||
, startWidgets = [ myWorkspaces, myLayout ]
|
||||
}
|
||||
)
|
||||
, ( "strixi-minaj"
|
||||
, baseConfig { endWidgets = laptopEndWidgets }
|
||||
, baseConfigX11 { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "jay-lenovo"
|
||||
, baseConfig { endWidgets = laptopEndWidgets }
|
||||
, baseConfigX11 { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "nixquick"
|
||||
, baseConfig { endWidgets = [ myTray , myMpris ] }
|
||||
, baseConfigX11 { endWidgets = [ myTray , myMpris ] }
|
||||
)
|
||||
|
||||
]
|
||||
waylandOverrides =
|
||||
[ ( "uber-loaner"
|
||||
, baseConfigWayland { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "adell"
|
||||
, baseConfigWayland { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "stevie-nixos"
|
||||
, baseConfigWayland { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "strixi-minaj"
|
||||
, baseConfigWayland { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "jay-lenovo"
|
||||
, baseConfigWayland { endWidgets = laptopEndWidgets }
|
||||
)
|
||||
, ( "nixquick"
|
||||
, baseConfigWayland { endWidgets = [ myTray , myMpris ] }
|
||||
)
|
||||
]
|
||||
selectedConfig =
|
||||
case backend of
|
||||
BackendX11 ->
|
||||
fromMaybe baseConfigX11 $ lookup hostName x11Overrides
|
||||
BackendWayland ->
|
||||
fromMaybe baseConfigWayland $ lookup hostName waylandOverrides
|
||||
simpleTaffyConfig = selectedConfig
|
||||
{ centerWidgets = [ myClock ]
|
||||
-- , endWidgets = []
|
||||
@@ -237,4 +388,4 @@ main = do
|
||||
appendHook (void $ getTrayHost False) $
|
||||
withLogServer $
|
||||
withToggleServer $
|
||||
toTaffyConfig simpleTaffyConfig
|
||||
toTaffybarConfig simpleTaffyConfig
|
||||
|
||||
Reference in New Issue
Block a user