taffybar config: stacked RAM/SWAP, barLevels tray row, bump locks
This commit is contained in:
4
dotfiles/config/taffybar/flake.lock
generated
4
dotfiles/config/taffybar/flake.lock
generated
@@ -554,8 +554,8 @@
|
|||||||
"xmonad-contrib": "xmonad-contrib"
|
"xmonad-contrib": "xmonad-contrib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770970544,
|
"lastModified": 1771379683,
|
||||||
"narHash": "sha256-rJV6yxYy77OJS994ICpNyecArjfhzGq6KKJrkbyYzvc=",
|
"narHash": "sha256-849/9t0hXF1Xwv6ygMWoZFGKwZ3xNqUSk2bSm4jZi/E=",
|
||||||
"path": "/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar",
|
"path": "/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
},
|
},
|
||||||
|
|||||||
Submodule dotfiles/config/taffybar/taffybar updated: 629e4941d7...0476afb1aa
@@ -30,6 +30,14 @@
|
|||||||
padding-right: 11px;
|
padding-right: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compact two-line RAM/SWAP widget: reduce icon padding a bit. */
|
||||||
|
.ram-swap .icon-label > .icon {
|
||||||
|
/* Different glyphs have different visual widths; fix the icon column width
|
||||||
|
so the value text aligns between the RAM and SWAP rows. */
|
||||||
|
min-width: 22px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* The main bar container. border-radius matches the widget squircles (6px)
|
/* The main bar container. border-radius matches the widget squircles (6px)
|
||||||
so the bar itself has softly rounded corners. */
|
so the bar itself has softly rounded corners. */
|
||||||
.taffy-box {
|
.taffy-box {
|
||||||
@@ -42,6 +50,18 @@
|
|||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* With barLevels enabled we render one row per level; keep the tray-only row
|
||||||
|
visually light so the tray feels detached from the main widget strip. */
|
||||||
|
.level-2 {
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-2 .outer-pad.sni-tray {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Each widget is wrapped in outer-pad > inner-pad > contents by
|
/* Each widget is wrapped in outer-pad > inner-pad > contents by
|
||||||
buildContentsBox (Haskell). The outer-pad draws the squircle
|
buildContentsBox (Haskell). The outer-pad draws the squircle
|
||||||
background pill. border-radius kept low (6px) for a more squared
|
background pill. border-radius kept low (6px) for a more squared
|
||||||
@@ -282,7 +302,8 @@
|
|||||||
|
|
||||||
.clock label,
|
.clock label,
|
||||||
.mpris label,
|
.mpris label,
|
||||||
.battery label {
|
.battery label,
|
||||||
|
.ram-swap label {
|
||||||
letter-spacing: 0.2px;
|
letter-spacing: 0.2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
|
import Control.Concurrent (threadDelay)
|
||||||
import Control.Monad.IO.Class (MonadIO, liftIO)
|
import Control.Monad.IO.Class (MonadIO, liftIO)
|
||||||
|
import Data.Char (toLower)
|
||||||
import Data.Int (Int32)
|
import Data.Int (Int32)
|
||||||
import Data.List (nub)
|
import Data.List (nub)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
@@ -15,7 +17,13 @@ import qualified Data.Text as T
|
|||||||
import qualified GI.GdkPixbuf.Objects.Pixbuf as Gdk
|
import qualified GI.GdkPixbuf.Objects.Pixbuf as Gdk
|
||||||
import qualified GI.Gtk as Gtk
|
import qualified GI.Gtk as Gtk
|
||||||
import Network.HostName (getHostName)
|
import Network.HostName (getHostName)
|
||||||
import qualified StatusNotifier.Tray as SNITray (MenuBackend (HaskellDBusMenu), defaultTrayParams, trayMenuBackend, trayOverlayScale)
|
import System.Environment (lookupEnv)
|
||||||
|
import qualified StatusNotifier.Tray as SNITray
|
||||||
|
( MenuBackend (HaskellDBusMenu, LibDBusMenu),
|
||||||
|
defaultTrayParams,
|
||||||
|
trayMenuBackend,
|
||||||
|
trayOverlayScale,
|
||||||
|
)
|
||||||
import System.Environment.XDG.BaseDir (getUserConfigFile)
|
import System.Environment.XDG.BaseDir (getUserConfigFile)
|
||||||
import System.Log.Logger (Priority (WARNING), rootLoggerName, setLevel, updateGlobalLogger)
|
import System.Log.Logger (Priority (WARNING), rootLoggerName, setLevel, updateGlobalLogger)
|
||||||
import System.Taffybar (startTaffybar)
|
import System.Taffybar (startTaffybar)
|
||||||
@@ -23,10 +31,11 @@ import System.Taffybar.Context (Backend (BackendWayland, BackendX11), TaffyIO, d
|
|||||||
import System.Taffybar.DBus
|
import System.Taffybar.DBus
|
||||||
import System.Taffybar.DBus.Toggle
|
import System.Taffybar.DBus.Toggle
|
||||||
import System.Taffybar.Hooks (withLogLevels)
|
import System.Taffybar.Hooks (withLogLevels)
|
||||||
|
import System.Taffybar.Information.Memory (MemoryInfo (..), parseMeminfo)
|
||||||
import System.Taffybar.Information.EWMHDesktopInfo (WorkspaceId (..))
|
import System.Taffybar.Information.EWMHDesktopInfo (WorkspaceId (..))
|
||||||
import System.Taffybar.Information.X11DesktopInfo
|
import System.Taffybar.Information.X11DesktopInfo
|
||||||
import System.Taffybar.SimpleConfig
|
import System.Taffybar.SimpleConfig
|
||||||
import System.Taffybar.Util (getPixbufFromFilePath, maybeTCombine, (<|||>))
|
import System.Taffybar.Util (getPixbufFromFilePath, maybeTCombine, postGUIASync, (<|||>))
|
||||||
import System.Taffybar.Widget
|
import System.Taffybar.Widget
|
||||||
import qualified System.Taffybar.Widget.ASUS as ASUS
|
import qualified System.Taffybar.Widget.ASUS as ASUS
|
||||||
import qualified System.Taffybar.Widget.NetworkManager as NetworkManager
|
import qualified System.Taffybar.Widget.NetworkManager as NetworkManager
|
||||||
@@ -37,12 +46,13 @@ import System.Taffybar.Widget.SNITray
|
|||||||
sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt,
|
sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt,
|
||||||
)
|
)
|
||||||
import qualified System.Taffybar.Widget.ScreenLock as ScreenLock
|
import qualified System.Taffybar.Widget.ScreenLock as ScreenLock
|
||||||
import System.Taffybar.Widget.Util (buildContentsBox, buildIconLabelBox, loadPixbufByName, widgetSetClassGI)
|
import System.Taffybar.Widget.Util (backgroundLoop, buildContentsBox, buildIconLabelBox, loadPixbufByName, widgetSetClassGI)
|
||||||
import qualified System.Taffybar.Widget.Wlsunset as Wlsunset
|
import qualified System.Taffybar.Widget.Wlsunset as Wlsunset
|
||||||
import qualified System.Taffybar.Widget.Workspaces.Config as WorkspaceWidgetConfig
|
import qualified System.Taffybar.Widget.Workspaces.Config as WorkspaceWidgetConfig
|
||||||
import qualified System.Taffybar.Widget.Workspaces.EWMH as X11Workspaces
|
import qualified System.Taffybar.Widget.Workspaces.EWMH as X11Workspaces
|
||||||
import qualified System.Taffybar.Widget.Workspaces.Hyprland as Hyprland
|
import qualified System.Taffybar.Widget.Workspaces.Hyprland as Hyprland
|
||||||
import System.Taffybar.WindowIcon (pixBufFromColor)
|
import System.Taffybar.WindowIcon (pixBufFromColor)
|
||||||
|
import Text.Printf (printf)
|
||||||
|
|
||||||
-- | Wrap the widget in a "TaffyBox" (via 'buildContentsBox') and add a CSS class.
|
-- | Wrap the widget in a "TaffyBox" (via 'buildContentsBox') and add a CSS class.
|
||||||
decorateWithClassAndBox :: (MonadIO m) => Text -> Gtk.Widget -> m Gtk.Widget
|
decorateWithClassAndBox :: (MonadIO m) => Text -> Gtk.Widget -> m Gtk.Widget
|
||||||
@@ -342,6 +352,78 @@ diskUsageWidget :: TaffyIO Gtk.Widget
|
|||||||
diskUsageWidget =
|
diskUsageWidget =
|
||||||
decorateWithClassAndBoxM "disk-usage" diskUsageNew
|
decorateWithClassAndBoxM "disk-usage" diskUsageNew
|
||||||
|
|
||||||
|
stackInPill :: Text -> [TaffyIO Gtk.Widget] -> TaffyIO Gtk.Widget
|
||||||
|
stackInPill klass builders =
|
||||||
|
decorateWithClassAndBoxM klass $ do
|
||||||
|
widgets <- sequence builders
|
||||||
|
liftIO $ do
|
||||||
|
box <- Gtk.boxNew Gtk.OrientationVertical 0
|
||||||
|
mapM_ (\w -> Gtk.boxPackStart box w False False 0) widgets
|
||||||
|
Gtk.widgetShowAll box
|
||||||
|
Gtk.toWidget box
|
||||||
|
|
||||||
|
meminfoPercentRowWidget ::
|
||||||
|
Text ->
|
||||||
|
Text ->
|
||||||
|
(MemoryInfo -> Maybe Double) ->
|
||||||
|
(MemoryInfo -> T.Text) ->
|
||||||
|
TaffyIO Gtk.Widget
|
||||||
|
meminfoPercentRowWidget rowClass iconText getRatio tooltipText =
|
||||||
|
liftIO $ do
|
||||||
|
iconW <- Gtk.toWidget =<< Gtk.labelNew (Just iconText)
|
||||||
|
valueLabel <- Gtk.labelNew (Just "")
|
||||||
|
valueW <- Gtk.toWidget valueLabel
|
||||||
|
row <- buildIconLabelBox iconW valueW
|
||||||
|
_ <- widgetSetClassGI row rowClass
|
||||||
|
|
||||||
|
let fmtPercent :: Double -> T.Text
|
||||||
|
fmtPercent r = T.pack (printf "%.0f%%" (max 0 r * 100))
|
||||||
|
updateOnce :: IO ()
|
||||||
|
updateOnce = do
|
||||||
|
info <- parseMeminfo
|
||||||
|
let valueText = maybe "n/a" fmtPercent (getRatio info)
|
||||||
|
postGUIASync $ do
|
||||||
|
Gtk.labelSetText valueLabel valueText
|
||||||
|
Gtk.widgetSetTooltipText row (Just (tooltipText info))
|
||||||
|
threadDelay (2 * 1000000)
|
||||||
|
|
||||||
|
_ <- Gtk.onWidgetRealize row $ backgroundLoop updateOnce
|
||||||
|
pure row
|
||||||
|
|
||||||
|
ramRowWidget :: TaffyIO Gtk.Widget
|
||||||
|
ramRowWidget =
|
||||||
|
meminfoPercentRowWidget
|
||||||
|
"ram-row"
|
||||||
|
"\xF538" -- Font Awesome: memory
|
||||||
|
(Just . memoryUsedRatio)
|
||||||
|
(\info -> "RAM " <> showMemoryInfo "$used$/$total$" 2 info)
|
||||||
|
|
||||||
|
swapRowWidget :: TaffyIO Gtk.Widget
|
||||||
|
swapRowWidget =
|
||||||
|
meminfoPercentRowWidget
|
||||||
|
"swap-row"
|
||||||
|
"\xF0EC" -- Font Awesome: exchange (swap-ish)
|
||||||
|
(\info -> if memorySwapTotal info <= 0 then Nothing else Just (memorySwapUsedRatio info))
|
||||||
|
(\info -> "SWAP " <> showMemoryInfo "$swapUsed$/$swapTotal$" 2 info)
|
||||||
|
|
||||||
|
ramSwapWidget :: TaffyIO Gtk.Widget
|
||||||
|
ramSwapWidget =
|
||||||
|
stackInPill "ram-swap" [ramRowWidget, swapRowWidget]
|
||||||
|
|
||||||
|
audioBacklightWidget :: TaffyIO Gtk.Widget
|
||||||
|
audioBacklightWidget =
|
||||||
|
stackInPill
|
||||||
|
"audio-backlight"
|
||||||
|
[ PulseAudio.pulseAudioNew,
|
||||||
|
backlightNewChanWith
|
||||||
|
defaultBacklightWidgetConfig
|
||||||
|
{ backlightFormat = "$percent$%",
|
||||||
|
backlightUnknownFormat = "n/a",
|
||||||
|
backlightTooltipFormat =
|
||||||
|
Just "Device: $device$\nBrightness: $brightness$/$max$ ($percent$%)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
asusWidget :: TaffyIO Gtk.Widget
|
asusWidget :: TaffyIO Gtk.Widget
|
||||||
asusWidget =
|
asusWidget =
|
||||||
decorateWithClassAndBoxM "asus-profile" ASUS.asusWidgetNew
|
decorateWithClassAndBoxM "asus-profile" ASUS.asusWidgetNew
|
||||||
@@ -363,10 +445,17 @@ wlsunsetWidget =
|
|||||||
}
|
}
|
||||||
|
|
||||||
sniTrayWidget :: TaffyIO Gtk.Widget
|
sniTrayWidget :: TaffyIO Gtk.Widget
|
||||||
sniTrayWidget =
|
sniTrayWidget = do
|
||||||
|
-- If the Haskell backend regresses, flip at runtime:
|
||||||
|
-- TAFFYBAR_SNI_MENU_BACKEND=lib
|
||||||
|
backendEnv <- liftIO (lookupEnv "TAFFYBAR_SNI_MENU_BACKEND")
|
||||||
|
let menuBackend =
|
||||||
|
case fmap (map toLower) backendEnv of
|
||||||
|
Just "lib" -> SNITray.LibDBusMenu
|
||||||
|
_ -> SNITray.HaskellDBusMenu
|
||||||
decorateWithClassAndBoxM
|
decorateWithClassAndBoxM
|
||||||
"sni-tray"
|
"sni-tray"
|
||||||
(sniTrayNewFromParams (SNITray.defaultTrayParams {SNITray.trayMenuBackend = SNITray.HaskellDBusMenu, SNITray.trayOverlayScale = 1 % 3}))
|
(sniTrayNewFromParams (SNITray.defaultTrayParams {SNITray.trayMenuBackend = menuBackend, SNITray.trayOverlayScale = 1 % 3}))
|
||||||
|
|
||||||
-- ** Layout
|
-- ** Layout
|
||||||
|
|
||||||
@@ -377,16 +466,15 @@ startWidgetsForBackend backend =
|
|||||||
-- These Wayland widgets are Hyprland-specific.
|
-- These Wayland widgets are Hyprland-specific.
|
||||||
BackendWayland -> [hyprlandWorkspacesWidget]
|
BackendWayland -> [hyprlandWorkspacesWidget]
|
||||||
|
|
||||||
endWidgetsForHost :: String -> Backend -> [TaffyIO Gtk.Widget]
|
endWidgetsForHost :: String -> [TaffyIO Gtk.Widget]
|
||||||
endWidgetsForHost hostName backend =
|
endWidgetsForHost hostName =
|
||||||
let baseEndWidgets = [audioWidget, diskUsageWidget, networkWidget, screenLockWidget, wlsunsetWidget, mprisWidget, sniTrayWidget]
|
let baseEndWidgets = [audioWidget, ramSwapWidget, diskUsageWidget, networkWidget, screenLockWidget, wlsunsetWidget, mprisWidget]
|
||||||
laptopEndWidgets =
|
laptopEndWidgets =
|
||||||
[ batteryWidget,
|
[ batteryWidget,
|
||||||
sniTrayWidget,
|
|
||||||
asusWidget,
|
asusWidget,
|
||||||
audioWidget,
|
audioBacklightWidget,
|
||||||
|
ramSwapWidget,
|
||||||
diskUsageWidget,
|
diskUsageWidget,
|
||||||
backlightWidget,
|
|
||||||
networkWidget,
|
networkWidget,
|
||||||
screenLockWidget,
|
screenLockWidget,
|
||||||
wlsunsetWidget,
|
wlsunsetWidget,
|
||||||
@@ -396,17 +484,32 @@ endWidgetsForHost hostName backend =
|
|||||||
then laptopEndWidgets
|
then laptopEndWidgets
|
||||||
else baseEndWidgets
|
else baseEndWidgets
|
||||||
|
|
||||||
|
barLevelsForHost :: String -> Backend -> [BarLevelConfig]
|
||||||
|
barLevelsForHost hostName backend =
|
||||||
|
[ BarLevelConfig
|
||||||
|
{ levelStartWidgets = startWidgetsForBackend backend,
|
||||||
|
levelCenterWidgets = [clockWidget],
|
||||||
|
levelEndWidgets = endWidgetsForHost hostName
|
||||||
|
},
|
||||||
|
BarLevelConfig
|
||||||
|
{ levelStartWidgets = [],
|
||||||
|
levelCenterWidgets = [],
|
||||||
|
levelEndWidgets = [sniTrayWidget]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
mkSimpleTaffyConfig :: String -> Backend -> [FilePath] -> SimpleTaffyConfig
|
mkSimpleTaffyConfig :: String -> Backend -> [FilePath] -> SimpleTaffyConfig
|
||||||
mkSimpleTaffyConfig hostName backend cssFiles =
|
mkSimpleTaffyConfig hostName backend cssFiles =
|
||||||
defaultSimpleTaffyConfig
|
defaultSimpleTaffyConfig
|
||||||
{ startWidgets = startWidgetsForBackend backend,
|
{ startWidgets = [],
|
||||||
endWidgets = endWidgetsForHost hostName backend,
|
centerWidgets = [],
|
||||||
|
endWidgets = [],
|
||||||
|
barLevels = Just $ barLevelsForHost hostName backend,
|
||||||
barPosition = Top,
|
barPosition = Top,
|
||||||
widgetSpacing = 0,
|
widgetSpacing = 0,
|
||||||
barPadding = 4,
|
barPadding = 4,
|
||||||
barHeight = ScreenRatio $ 1 / 33,
|
barHeight = ScreenRatio $ 1 / 33,
|
||||||
cssPaths = cssFiles,
|
cssPaths = cssFiles
|
||||||
centerWidgets = [clockWidget]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- ** Entry Point
|
-- ** Entry Point
|
||||||
|
|||||||
12
nixos/flake.lock
generated
12
nixos/flake.lock
generated
@@ -1910,11 +1910,11 @@
|
|||||||
"status-notifier-item": {
|
"status-notifier-item": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770970375,
|
"lastModified": 1770955859,
|
||||||
"narHash": "sha256-0G5dkc1bjAdbAJBBnipeEE2HbEkd4+bdkyRraumMRs4=",
|
"narHash": "sha256-h95eUeTkNsdrVxAx0Nv0ViXHSkhhOfPF4L4DhtbfkNs=",
|
||||||
"owner": "taffybar",
|
"owner": "taffybar",
|
||||||
"repo": "status-notifier-item",
|
"repo": "status-notifier-item",
|
||||||
"rev": "233aa43606036d06e58f19be156c48fa979506f2",
|
"rev": "a0958505f4e5fc145f34d7ad2615688d6668e02a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1990,11 +1990,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770971159,
|
"lastModified": 1770956839,
|
||||||
"narHash": "sha256-FOMr9QGs6dzQ0AHfvq0/s5H8I8IWVl347h2NCu+Upz8=",
|
"narHash": "sha256-LeFbcQ1i7PBbSNhGFkf6A2yj71NnWjJj0ASahmxaxwg=",
|
||||||
"owner": "taffybar",
|
"owner": "taffybar",
|
||||||
"repo": "taffybar",
|
"repo": "taffybar",
|
||||||
"rev": "276ed1fd83bb56d22cb854acb10aeebf64b97c5c",
|
"rev": "6a1cf87c87e4bcab01b81d5f7d257c4dc6cfa1af",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
Reference in New Issue
Block a user