remove ivanm-dfinity-razer and uber-loaner host references
Both hosts are long dead. Removes their CSS files, taffybar host config entries, and synergy aliases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,211 +0,0 @@
|
|||||||
@define-color transparent rgba(0.0, 0.0, 0.0, 0.0);
|
|
||||||
@define-color white #FFFFFF;
|
|
||||||
@define-color black #000000;
|
|
||||||
@define-color taffy-blue #0c7cd5;
|
|
||||||
|
|
||||||
@define-color active-window-color @white;
|
|
||||||
@define-color urgent-window-color @taffy-blue;
|
|
||||||
@define-color font-color @white;
|
|
||||||
@define-color menu-background-color @white;
|
|
||||||
@define-color menu-font-color @black;
|
|
||||||
|
|
||||||
/* Top level styling */
|
|
||||||
|
|
||||||
.taffy-window * {
|
|
||||||
font-family: "Noto Sans", sans-serif;
|
|
||||||
font-size: 10pt;
|
|
||||||
color: @font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-box {
|
|
||||||
border-color: @white;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-pad {
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contents {
|
|
||||||
padding: 1px;
|
|
||||||
transition: border-color .5s, background-color .5s, border-style 3s;
|
|
||||||
border-radius: 6px;
|
|
||||||
/* This transparent border is needed because we will run in to sizing issues
|
|
||||||
without it because we only check sizing one time. */
|
|
||||||
border-color: @transparent;
|
|
||||||
border-width: 2px;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Workspaces styling */
|
|
||||||
|
|
||||||
.workspace-label {
|
|
||||||
padding-right: 3px;
|
|
||||||
padding-left: 2px;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active .contents {
|
|
||||||
background-color: rgba(0.0, 0.0, 0.0, 0.2);
|
|
||||||
border-color: @font-color;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.visible .contents {
|
|
||||||
background-color: rgba(0.0, 0.0, 0.0, 0.2);
|
|
||||||
border-style: dotted;
|
|
||||||
border-color: @font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container {
|
|
||||||
transition: opacity .5s, box-shadow .5s, background-color .5s;
|
|
||||||
opacity: 1;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This gives space for the box-shadow (they look like underlines) that follow.
|
|
||||||
This will actually affect all widgets, (not just the workspace icons), but
|
|
||||||
that is what we want since we want the icons to look the same. */
|
|
||||||
.auto-size-image, .sni-tray {
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.active {
|
|
||||||
background-color: @font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.urgent {
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.inactive .window-icon {
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.minimized .window-icon {
|
|
||||||
opacity: .3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity .5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Button styling */
|
|
||||||
|
|
||||||
.taffy-window button {
|
|
||||||
all: initial;
|
|
||||||
background-color: @transparent;
|
|
||||||
border-width: 0px;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window button:checked, .taffy-window button:hover .Contents:hover {
|
|
||||||
box-shadow: inset 0 -3px @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Menu styling */
|
|
||||||
|
|
||||||
/* The ".taffy-window" prefixed selectors are needed because if they aren't present,
|
|
||||||
the top level .Taffybar selector takes precedence */
|
|
||||||
.taffy-window menuitem *, menuitem * {
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force an opaque background for menus, regardless of the system GTK theme. */
|
|
||||||
.taffy-window menu, menu,
|
|
||||||
.taffy-window menu.background, menu.background,
|
|
||||||
.taffy-window .menu, .menu,
|
|
||||||
.taffy-window .menu.background, .menu.background,
|
|
||||||
GtkMenu, GtkMenu.background {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.20);
|
|
||||||
padding: 4px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menu, menu {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some themes apply transparency to the menu's toplevel popup window. */
|
|
||||||
window.popup, window.popup.background,
|
|
||||||
window.menu, window.menu.background,
|
|
||||||
.menu, .menu.background {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup *, window.menu * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup decoration, window.menu decoration {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menuitem, menuitem {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem, GtkMenu menuitem, .menu menuitem {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menuitem:hover, menuitem:hover {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem:hover, GtkMenu menuitem:hover, .menu menuitem:hover {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup menuitem:hover *, window.menu menuitem:hover * {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu *, GtkMenu *, .menu * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem:hover *, GtkMenu menuitem:hover *, .menu menuitem:hover * {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menuitem:hover > label, menuitem:hover > label {
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some menus (notably a few StatusNotifierItem menus) are rendered as popovers
|
|
||||||
containing modelbuttons instead of menuitems. */
|
|
||||||
popover, popover.background, popover > contents {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.20);
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton, popover modelbutton * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton:hover {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton:hover > label {
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton:hover * {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
@@ -1,118 +1,76 @@
|
|||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
module Main where
|
|
||||||
|
|
||||||
import Control.Exception.Base
|
module Main (main) where
|
||||||
import Control.Monad
|
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad (guard, when)
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.IO.Class (MonadIO, liftIO)
|
||||||
import Control.Monad.Trans.Reader
|
import Data.Int (Int32)
|
||||||
import qualified Data.ByteString.Char8 as BS
|
import Data.List (nub)
|
||||||
import Data.List
|
|
||||||
import Data.List.Split
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import Data.Maybe
|
import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe)
|
||||||
import qualified Data.Text
|
import Data.Text (Text)
|
||||||
import Data.Time
|
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 qualified GI.Gtk.Objects.Overlay as Gtk
|
import Network.HostName (getHostName)
|
||||||
import Network.HostName
|
import System.Directory (doesPathExist)
|
||||||
import System.Directory
|
import System.Environment (lookupEnv, setEnv, unsetEnv)
|
||||||
import System.Environment
|
import System.Environment.XDG.BaseDir (getUserConfigFile)
|
||||||
import System.Environment.XDG.BaseDir
|
import System.FilePath.Posix ((</>))
|
||||||
import System.FilePath.Posix
|
import System.Log.Logger (Priority (..), getLogger, logM, saveGlobalLogger, setLevel)
|
||||||
import System.IO
|
import System.Taffybar (startTaffybar)
|
||||||
import System.Log.Handler.Simple
|
import System.Taffybar.Context (Backend (BackendWayland, BackendX11), TaffyIO, detectBackend)
|
||||||
import System.Log.Logger
|
|
||||||
import System.Process
|
|
||||||
import System.Taffybar
|
|
||||||
import System.Taffybar.Context (Backend(..), TaffyIO, appendHook, detectBackend)
|
|
||||||
import System.Taffybar.DBus
|
import System.Taffybar.DBus
|
||||||
import System.Taffybar.DBus.Toggle
|
import System.Taffybar.DBus.Toggle
|
||||||
import System.Taffybar.Hooks
|
import System.Taffybar.Information.EWMHDesktopInfo (WorkspaceId (..))
|
||||||
import System.Taffybar.Information.CPU
|
|
||||||
import System.Taffybar.Information.EWMHDesktopInfo
|
|
||||||
import System.Taffybar.Information.Memory
|
|
||||||
import System.Taffybar.Information.X11DesktopInfo
|
import System.Taffybar.Information.X11DesktopInfo
|
||||||
import System.Taffybar.SimpleConfig
|
import System.Taffybar.SimpleConfig
|
||||||
import System.Taffybar.Util
|
import System.Taffybar.Util (getPixbufFromFilePath, (<|||>), maybeTCombine)
|
||||||
import System.Taffybar.Widget
|
import System.Taffybar.Widget
|
||||||
import System.Taffybar.Widget.Generic.Icon
|
import qualified System.Taffybar.Widget.HyprlandWorkspaces as Hyprland
|
||||||
import System.Taffybar.Widget.Generic.PollingGraph
|
|
||||||
import System.Taffybar.Widget.Generic.PollingLabel
|
|
||||||
import qualified System.Taffybar.Widget.NetworkManager as NetworkManager
|
import qualified System.Taffybar.Widget.NetworkManager as NetworkManager
|
||||||
import qualified System.Taffybar.Widget.PulseAudio as PulseAudio
|
import qualified System.Taffybar.Widget.PulseAudio as PulseAudio
|
||||||
import System.Taffybar.Widget.SNITray
|
import System.Taffybar.Widget.SNITray
|
||||||
( sniTrayNew
|
( sniTrayNew
|
||||||
, sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt
|
, sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt
|
||||||
)
|
)
|
||||||
import System.Taffybar.Widget.Util
|
import System.Taffybar.Widget.Util (buildContentsBox, loadPixbufByName, widgetSetClassGI)
|
||||||
import qualified System.Taffybar.Widget.HyprlandWorkspaces as Hyprland
|
|
||||||
import qualified System.Taffybar.Widget.Workspaces as X11Workspaces
|
import qualified System.Taffybar.Widget.Workspaces as X11Workspaces
|
||||||
import System.Taffybar.WindowIcon (pixBufFromColor)
|
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
|
-- | Wrap the widget in a "TaffyBox" (via 'buildContentsBox') and add a CSS class.
|
||||||
setClassAndBoundingBoxes klass = buildContentsBox >=> flip widgetSetClassGI klass
|
decorateWithClassAndBox :: MonadIO m => Text -> Gtk.Widget -> m Gtk.Widget
|
||||||
|
decorateWithClassAndBox klass widget = do
|
||||||
|
boxed <- buildContentsBox widget
|
||||||
|
widgetSetClassGI boxed klass
|
||||||
|
|
||||||
deocrateWithSetClassAndBoxes :: MonadIO m => Data.Text.Text -> m Gtk.Widget -> m Gtk.Widget
|
decorateWithClassAndBoxM :: MonadIO m => Text -> m Gtk.Widget -> m Gtk.Widget
|
||||||
deocrateWithSetClassAndBoxes klass builder = builder >>= setClassAndBoundingBoxes klass
|
decorateWithClassAndBoxM klass builder =
|
||||||
|
builder >>= decorateWithClassAndBox klass
|
||||||
|
|
||||||
mkRGBA (r, g, b, a) = (r/256, g/256, b/256, a/256)
|
-- ** X11 Workspaces
|
||||||
blue = mkRGBA (42, 99, 140, 256)
|
|
||||||
yellow1 = mkRGBA (242, 163, 54, 256)
|
|
||||||
yellow2 = mkRGBA (254, 204, 83, 256)
|
|
||||||
yellow3 = mkRGBA (227, 134, 18, 256)
|
|
||||||
red = mkRGBA (210, 77, 37, 256)
|
|
||||||
|
|
||||||
myGraphConfig =
|
x11FullWorkspaceNames :: X11Property [(WorkspaceId, String)]
|
||||||
defaultGraphConfig
|
x11FullWorkspaceNames =
|
||||||
{ graphPadding = 0
|
go <$> readAsListOfString Nothing "_NET_DESKTOP_FULL_NAMES"
|
||||||
, graphBorderWidth = 0
|
where
|
||||||
, graphWidth = 75
|
go = zip [WorkspaceId i | i <- [0 ..]]
|
||||||
, graphBackgroundColor = (0.0, 0.0, 0.0, 0.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
netCfg = myGraphConfig
|
x11WorkspaceLabelSetter :: X11Workspaces.Workspace -> X11Workspaces.WorkspacesIO String
|
||||||
{ graphDataColors = [yellow1, yellow2]
|
x11WorkspaceLabelSetter workspace =
|
||||||
, graphLabel = Just "net"
|
|
||||||
}
|
|
||||||
|
|
||||||
memCfg = myGraphConfig
|
|
||||||
{ graphDataColors = [(0.129, 0.588, 0.953, 1)]
|
|
||||||
, graphLabel = Just "mem"
|
|
||||||
}
|
|
||||||
|
|
||||||
cpuCfg = myGraphConfig
|
|
||||||
{ graphDataColors = [red, (1, 0, 1, 0.5)]
|
|
||||||
, graphLabel = Just "cpu"
|
|
||||||
}
|
|
||||||
|
|
||||||
memCallback :: IO [Double]
|
|
||||||
memCallback = do
|
|
||||||
mi <- parseMeminfo
|
|
||||||
return [memoryUsedRatio mi]
|
|
||||||
|
|
||||||
cpuCallback = do
|
|
||||||
(_, systemLoad, totalLoad) <- cpuLoad
|
|
||||||
return [totalLoad, systemLoad]
|
|
||||||
|
|
||||||
getFullWorkspaceNames :: X11Property [(WorkspaceId, String)]
|
|
||||||
getFullWorkspaceNames = go <$> readAsListOfString Nothing "_NET_DESKTOP_FULL_NAMES"
|
|
||||||
where go = zip [WorkspaceId i | i <- [0..]]
|
|
||||||
|
|
||||||
workspaceNamesLabelSetter workspace =
|
|
||||||
remapNSP . fromMaybe "" . lookup (X11Workspaces.workspaceIdx workspace) <$>
|
remapNSP . fromMaybe "" . lookup (X11Workspaces.workspaceIdx workspace) <$>
|
||||||
liftX11Def [] getFullWorkspaceNames
|
liftX11Def [] x11FullWorkspaceNames
|
||||||
where remapNSP "NSP" = "S"
|
where
|
||||||
remapNSP n = n
|
remapNSP "NSP" = "S"
|
||||||
|
remapNSP n = n
|
||||||
|
|
||||||
enableLogger logger level = do
|
-- ** Logging
|
||||||
logger <- getLogger logger
|
|
||||||
|
enableLogger :: String -> Priority -> IO ()
|
||||||
|
enableLogger loggerName level = do
|
||||||
|
logger <- getLogger loggerName
|
||||||
saveGlobalLogger $ setLevel level logger
|
saveGlobalLogger $ setLevel level logger
|
||||||
|
|
||||||
-- Systemd --user's manager environment can be stale across logins (e.g. still
|
-- Systemd --user's manager environment can be stale across logins (e.g. still
|
||||||
@@ -149,48 +107,34 @@ detectBackendRobust = do
|
|||||||
when (isJust mHyprSig) $ unsetEnv "HYPRLAND_INSTANCE_SIGNATURE"
|
when (isJust mHyprSig) $ unsetEnv "HYPRLAND_INSTANCE_SIGNATURE"
|
||||||
when (mSessionType == Just "wayland") $ setEnv "XDG_SESSION_TYPE" "x11"
|
when (mSessionType == Just "wayland") $ setEnv "XDG_SESSION_TYPE" "x11"
|
||||||
|
|
||||||
case () of
|
let x11Ok = maybe False (not . null) mDisplay
|
||||||
_ | waylandOk -> pure BackendWayland
|
if waylandOk
|
||||||
| maybe False (not . null) mDisplay -> pure BackendX11
|
then pure BackendWayland
|
||||||
| otherwise -> detectBackend
|
else if x11Ok
|
||||||
|
then pure BackendX11
|
||||||
|
else detectBackend
|
||||||
|
|
||||||
logDebug = do
|
-- ** Hyprland Icon Finding
|
||||||
global <- getLogger ""
|
|
||||||
saveGlobalLogger $ setLevel DEBUG global
|
|
||||||
logger3 <- getLogger "System.Taffybar"
|
|
||||||
saveGlobalLogger $ setLevel DEBUG logger3
|
|
||||||
logger <- getLogger "System.Taffybar.Widget.Generic.AutoSizeImage"
|
|
||||||
saveGlobalLogger $ setLevel DEBUG logger
|
|
||||||
logger2 <- getLogger "StatusNotifier.Tray"
|
|
||||||
saveGlobalLogger $ setLevel DEBUG logger2
|
|
||||||
-- workspacesLogger <- getLogger "System.Taffybar.Widget.Workspaces"
|
|
||||||
-- saveGlobalLogger $ setLevel WARNING workspacesLogger
|
|
||||||
-- logDebug
|
|
||||||
-- logM "What" WARNING "Why"
|
|
||||||
-- enableLogger "System.Taffybar.Widget.Util" DEBUG
|
|
||||||
-- enableLogger "System.Taffybar.Information.XDG.DesktopEntry" DEBUG
|
|
||||||
-- enableLogger "System.Taffybar.WindowIcon" DEBUG
|
|
||||||
-- enableLogger "System.Taffybar.Widget.Generic.PollingLabel" DEBUG
|
|
||||||
|
|
||||||
iconRemap :: [(Data.Text.Text, [Data.Text.Text])]
|
iconRemap :: [(Text, [Text])]
|
||||||
iconRemap =
|
iconRemap =
|
||||||
[ ("spotify", ["spotify-client", "spotify"])
|
[ ("spotify", ["spotify-client", "spotify"])
|
||||||
]
|
]
|
||||||
|
|
||||||
iconRemapMap :: M.Map Data.Text.Text [Data.Text.Text]
|
iconRemapMap :: M.Map Text [Text]
|
||||||
iconRemapMap =
|
iconRemapMap =
|
||||||
M.fromList [ (Data.Text.toLower k, v) | (k, v) <- iconRemap ]
|
M.fromList [ (T.toLower k, v) | (k, v) <- iconRemap ]
|
||||||
|
|
||||||
lookupIconRemap :: Data.Text.Text -> [Data.Text.Text]
|
lookupIconRemap :: Text -> [Text]
|
||||||
lookupIconRemap name = fromMaybe [] $ M.lookup (Data.Text.toLower name) iconRemapMap
|
lookupIconRemap name = fromMaybe [] $ M.lookup (T.toLower name) iconRemapMap
|
||||||
|
|
||||||
iconNameVariants :: Data.Text.Text -> [Data.Text.Text]
|
iconNameVariants :: Text -> [Text]
|
||||||
iconNameVariants raw =
|
iconNameVariants raw =
|
||||||
let lower = Data.Text.toLower raw
|
let lower = T.toLower raw
|
||||||
stripped = fromMaybe lower (Data.Text.stripSuffix ".desktop" lower)
|
stripped = fromMaybe lower (T.stripSuffix ".desktop" lower)
|
||||||
suffixes = ["-gtk", "-client", "-desktop"]
|
suffixes = ["-gtk", "-client", "-desktop"]
|
||||||
stripSuffixes name =
|
stripSuffixes name =
|
||||||
let variants = mapMaybe (`Data.Text.stripSuffix` name) suffixes
|
let variants = mapMaybe (`T.stripSuffix` name) suffixes
|
||||||
in nub $ variants ++ [name]
|
in nub $ variants ++ [name]
|
||||||
baseNames = stripSuffixes stripped ++ [raw]
|
baseNames = stripSuffixes stripped ++ [raw]
|
||||||
toDash c
|
toDash c
|
||||||
@@ -201,13 +145,13 @@ iconNameVariants raw =
|
|||||||
| otherwise = c
|
| otherwise = c
|
||||||
variantsFor name =
|
variantsFor name =
|
||||||
let dotted =
|
let dotted =
|
||||||
case Data.Text.splitOn "." name of
|
case T.splitOn "." name of
|
||||||
[] -> name
|
[] -> name
|
||||||
xs -> last xs
|
xs -> last xs
|
||||||
dashed = Data.Text.map toDash name
|
dashed = T.map toDash name
|
||||||
dashedDotted = Data.Text.map toDash dotted
|
dashedDotted = T.map toDash dotted
|
||||||
underscored = Data.Text.map toUnderscore name
|
underscored = T.map toUnderscore name
|
||||||
underscoredDotted = Data.Text.map toUnderscore dotted
|
underscoredDotted = T.map toUnderscore dotted
|
||||||
in [dotted, dashed, dashedDotted, underscored, underscoredDotted, name]
|
in [dotted, dashed, dashedDotted, underscored, underscoredDotted, name]
|
||||||
in nub $ concatMap variantsFor baseNames
|
in nub $ concatMap variantsFor baseNames
|
||||||
|
|
||||||
@@ -215,12 +159,12 @@ iconNameVariants raw =
|
|||||||
-- usually not something we want visible in the workspace widget.
|
-- usually not something we want visible in the workspace widget.
|
||||||
isSpecialHyprWorkspace :: Hyprland.HyprlandWorkspace -> Bool
|
isSpecialHyprWorkspace :: Hyprland.HyprlandWorkspace -> Bool
|
||||||
isSpecialHyprWorkspace ws =
|
isSpecialHyprWorkspace ws =
|
||||||
let name = Data.Text.toLower $ Data.Text.pack $ Hyprland.workspaceName ws
|
let name = T.toLower $ T.pack $ Hyprland.workspaceName ws
|
||||||
in Data.Text.isPrefixOf "special" name || Hyprland.workspaceIdx ws < 0
|
in T.isPrefixOf "special" name || Hyprland.workspaceIdx ws < 0
|
||||||
|
|
||||||
hyprlandIconCandidates :: Hyprland.HyprlandWindow -> [Data.Text.Text]
|
hyprlandIconCandidates :: Hyprland.HyprlandWindow -> [Text]
|
||||||
hyprlandIconCandidates windowData =
|
hyprlandIconCandidates windowData =
|
||||||
let baseNames = map Data.Text.pack $ catMaybes
|
let baseNames = map T.pack $ catMaybes
|
||||||
[ Hyprland.windowClass windowData
|
[ Hyprland.windowClass windowData
|
||||||
, Hyprland.windowInitialClass windowData
|
, Hyprland.windowInitialClass windowData
|
||||||
]
|
]
|
||||||
@@ -229,17 +173,18 @@ hyprlandIconCandidates windowData =
|
|||||||
baseExpanded = concatMap iconNameVariants baseNames
|
baseExpanded = concatMap iconNameVariants baseNames
|
||||||
in nub (remappedExpanded ++ baseExpanded)
|
in nub (remappedExpanded ++ baseExpanded)
|
||||||
|
|
||||||
isPathCandidate :: Data.Text.Text -> Bool
|
isPathCandidate :: Text -> Bool
|
||||||
isPathCandidate name =
|
isPathCandidate name =
|
||||||
Data.Text.isInfixOf "/" name ||
|
T.isInfixOf "/" name ||
|
||||||
any (`Data.Text.isSuffixOf` name) [".png", ".svg", ".xpm"]
|
any (`T.isSuffixOf` name) [".png", ".svg", ".xpm"]
|
||||||
|
|
||||||
|
hyprlandIconFromCandidate :: Int32 -> Text -> TaffyIO (Maybe Gdk.Pixbuf)
|
||||||
hyprlandIconFromCandidate size name
|
hyprlandIconFromCandidate size name
|
||||||
| isPathCandidate name =
|
| isPathCandidate name =
|
||||||
liftIO $ getPixbufFromFilePath (Data.Text.unpack name)
|
liftIO $ getPixbufFromFilePath (T.unpack name)
|
||||||
| otherwise =
|
| otherwise =
|
||||||
maybeTCombine
|
maybeTCombine
|
||||||
(Hyprland.getWindowIconFromDesktopEntryByAppId size (Data.Text.unpack name))
|
(Hyprland.getWindowIconFromDesktopEntryByAppId size (T.unpack name))
|
||||||
(liftIO $ loadPixbufByName size name)
|
(liftIO $ loadPixbufByName size name)
|
||||||
|
|
||||||
hyprlandManualIconGetter :: Hyprland.HyprlandWindowIconPixbufGetter
|
hyprlandManualIconGetter :: Hyprland.HyprlandWindowIconPixbufGetter
|
||||||
@@ -274,124 +219,210 @@ hyprlandFallbackIcon :: Hyprland.HyprlandWindowIconPixbufGetter
|
|||||||
hyprlandFallbackIcon size _ =
|
hyprlandFallbackIcon size _ =
|
||||||
fallbackIconPixbuf size
|
fallbackIconPixbuf size
|
||||||
|
|
||||||
|
-- ** Host Overrides
|
||||||
|
|
||||||
|
defaultCssFiles :: [FilePath]
|
||||||
|
defaultCssFiles = ["palette.css", "taffybar.css"]
|
||||||
|
|
||||||
|
cssFilesByHostname :: [(String, [FilePath])]
|
||||||
cssFilesByHostname =
|
cssFilesByHostname =
|
||||||
[ ("uber-loaner", ["palette.css", "uber-loaner.css"])
|
[ ("imalison-home", ["palette.css", "taffybar.css"])
|
||||||
, ("imalison-home", ["palette.css", "taffybar.css"])
|
|
||||||
, ("ivanm-dfinity-razer", ["palette.css", "taffybar.css"])
|
|
||||||
, ("ryzen-shine", ["palette.css", "taffybar.css"])
|
, ("ryzen-shine", ["palette.css", "taffybar.css"])
|
||||||
, ("stevie-nixos", ["palette.css", "taffybar.css"])
|
, ("stevie-nixos", ["palette.css", "taffybar.css"])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
laptopHosts :: [String]
|
||||||
|
laptopHosts =
|
||||||
|
[ "adell"
|
||||||
|
, "stevie-nixos"
|
||||||
|
, "strixi-minaj"
|
||||||
|
, "jay-lenovo"
|
||||||
|
]
|
||||||
|
|
||||||
|
cssFilesForHost :: String -> [FilePath]
|
||||||
|
cssFilesForHost hostName =
|
||||||
|
fromMaybe defaultCssFiles $ lookup hostName cssFilesByHostname
|
||||||
|
|
||||||
|
-- ** Widgets
|
||||||
|
|
||||||
|
audioWidget :: TaffyIO Gtk.Widget
|
||||||
|
audioWidget =
|
||||||
|
decorateWithClassAndBoxM "audio" PulseAudio.pulseAudioLabelNew
|
||||||
|
|
||||||
|
networkWidget :: TaffyIO Gtk.Widget
|
||||||
|
networkWidget =
|
||||||
|
decorateWithClassAndBoxM "network" NetworkManager.networkManagerWifiLabelNew
|
||||||
|
|
||||||
|
layoutWidget :: TaffyIO Gtk.Widget
|
||||||
|
layoutWidget =
|
||||||
|
decorateWithClassAndBoxM "layout" (layoutNew defaultLayoutConfig)
|
||||||
|
|
||||||
|
windowsWidget :: TaffyIO Gtk.Widget
|
||||||
|
windowsWidget =
|
||||||
|
decorateWithClassAndBoxM "windows" (windowsNew defaultWindowsConfig)
|
||||||
|
|
||||||
|
x11WorkspacesWidget :: TaffyIO Gtk.Widget
|
||||||
|
x11WorkspacesWidget =
|
||||||
|
flip widgetSetClassGI "workspaces" =<<
|
||||||
|
X11Workspaces.workspacesNew
|
||||||
|
X11Workspaces.defaultWorkspacesConfig
|
||||||
|
{ X11Workspaces.minIcons = 1
|
||||||
|
, X11Workspaces.getWindowIconPixbuf =
|
||||||
|
X11Workspaces.scaledWindowIconPixbufGetter $
|
||||||
|
X11Workspaces.getWindowIconPixbufFromChrome <|||>
|
||||||
|
X11Workspaces.unscaledDefaultGetWindowIconPixbuf <|||>
|
||||||
|
(\size _ -> fallbackIconPixbuf size)
|
||||||
|
, X11Workspaces.widgetGap = 0
|
||||||
|
, X11Workspaces.showWorkspaceFn = X11Workspaces.hideEmpty
|
||||||
|
, X11Workspaces.updateRateLimitMicroseconds = 100000
|
||||||
|
, X11Workspaces.labelSetter = x11WorkspaceLabelSetter
|
||||||
|
, X11Workspaces.widgetBuilder = X11Workspaces.buildLabelOverlayController
|
||||||
|
}
|
||||||
|
|
||||||
|
-- | Like 'buildWorkspaceIconLabelOverlay' but lets you choose the corner.
|
||||||
|
buildAlignedOverlay ::
|
||||||
|
Gtk.Align -> Gtk.Align -> Gtk.Widget -> Gtk.Widget -> TaffyIO Gtk.Widget
|
||||||
|
buildAlignedOverlay halign valign iconsWidget labelWidget = liftIO $ do
|
||||||
|
base <- buildContentsBox iconsWidget
|
||||||
|
ebox <- Gtk.eventBoxNew
|
||||||
|
_ <- widgetSetClassGI ebox "overlay-box"
|
||||||
|
Gtk.widgetSetHalign ebox halign
|
||||||
|
Gtk.widgetSetValign ebox valign
|
||||||
|
Gtk.containerAdd ebox labelWidget
|
||||||
|
overlayLabel <- Gtk.toWidget ebox
|
||||||
|
overlay <- Gtk.overlayNew
|
||||||
|
baseW <- Gtk.toWidget base
|
||||||
|
Gtk.containerAdd overlay baseW
|
||||||
|
Gtk.overlayAddOverlay overlay overlayLabel
|
||||||
|
Gtk.overlaySetOverlayPassThrough overlay overlayLabel True
|
||||||
|
Gtk.toWidget overlay
|
||||||
|
|
||||||
|
hyprlandWorkspacesWidget :: TaffyIO Gtk.Widget
|
||||||
|
hyprlandWorkspacesWidget =
|
||||||
|
flip widgetSetClassGI "workspaces" =<<
|
||||||
|
Hyprland.hyprlandWorkspacesNew
|
||||||
|
Hyprland.defaultHyprlandWorkspacesConfig
|
||||||
|
{ Hyprland.widgetGap = 0
|
||||||
|
, Hyprland.minIcons = 1
|
||||||
|
, Hyprland.widgetBuilder = buildAlignedOverlay Gtk.AlignStart Gtk.AlignEnd
|
||||||
|
-- Don't show Hyprland "special:*" workspaces.
|
||||||
|
, Hyprland.showWorkspaceFn =
|
||||||
|
\ws ->
|
||||||
|
Hyprland.workspaceState ws /= X11Workspaces.Empty &&
|
||||||
|
not (isSpecialHyprWorkspace ws)
|
||||||
|
, Hyprland.getWindowIconPixbuf =
|
||||||
|
hyprlandManualIconGetter <|||>
|
||||||
|
Hyprland.defaultHyprlandGetWindowIconPixbuf <|||>
|
||||||
|
hyprlandFallbackIcon
|
||||||
|
}
|
||||||
|
|
||||||
|
clockWidget :: TaffyIO Gtk.Widget
|
||||||
|
clockWidget =
|
||||||
|
decorateWithClassAndBoxM
|
||||||
|
"clock"
|
||||||
|
( textClockNewWith
|
||||||
|
defaultClockConfig
|
||||||
|
{ clockUpdateStrategy = RoundedTargetInterval 60 0.0
|
||||||
|
, clockFormatString = "%a %b %_d, 🕑%I:%M %p"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
mprisWidget :: TaffyIO Gtk.Widget
|
||||||
|
mprisWidget =
|
||||||
|
mpris2NewWithConfig
|
||||||
|
MPRIS2Config
|
||||||
|
{ mprisWidgetWrapper = decorateWithClassAndBox "mpris"
|
||||||
|
, updatePlayerWidget =
|
||||||
|
simplePlayerWidget
|
||||||
|
defaultPlayerConfig
|
||||||
|
{ setNowPlayingLabel = playingText 20 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
batteryIconWidget :: TaffyIO Gtk.Widget
|
||||||
|
batteryIconWidget =
|
||||||
|
decorateWithClassAndBoxM "battery-icon" batteryIconNew
|
||||||
|
|
||||||
|
batteryTextWidget :: TaffyIO Gtk.Widget
|
||||||
|
batteryTextWidget =
|
||||||
|
decorateWithClassAndBoxM "battery-text" (textBatteryNew "$percentage$%")
|
||||||
|
|
||||||
|
batteryWidgets :: [TaffyIO Gtk.Widget]
|
||||||
|
batteryWidgets = [batteryIconWidget, batteryTextWidget]
|
||||||
|
|
||||||
|
-- Note: end widgets are packed with Gtk.boxPackEnd; list order is right-to-left.
|
||||||
|
batteryEndWidgets :: [TaffyIO Gtk.Widget]
|
||||||
|
batteryEndWidgets = reverse batteryWidgets
|
||||||
|
|
||||||
|
backlightWidget :: TaffyIO Gtk.Widget
|
||||||
|
backlightWidget =
|
||||||
|
decorateWithClassAndBoxM
|
||||||
|
"backlight"
|
||||||
|
( backlightLabelNewChanWith
|
||||||
|
defaultBacklightWidgetConfig
|
||||||
|
{ backlightFormat = "☀ $percent$%"
|
||||||
|
, backlightUnknownFormat = "☀ n/a"
|
||||||
|
, backlightTooltipFormat =
|
||||||
|
Just "Device: $device$\nBrightness: $brightness$/$max$ ($percent$%)"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
sniTrayWidget :: TaffyIO Gtk.Widget
|
||||||
|
sniTrayWidget =
|
||||||
|
decorateWithClassAndBoxM
|
||||||
|
"sni-tray"
|
||||||
|
sniTrayNew
|
||||||
|
|
||||||
|
-- ** Layout
|
||||||
|
|
||||||
|
startWidgetsForBackend :: Backend -> [TaffyIO Gtk.Widget]
|
||||||
|
startWidgetsForBackend backend =
|
||||||
|
case backend of
|
||||||
|
BackendX11 -> [x11WorkspacesWidget, layoutWidget, windowsWidget]
|
||||||
|
-- These Wayland widgets are Hyprland-specific.
|
||||||
|
BackendWayland -> [hyprlandWorkspacesWidget]
|
||||||
|
|
||||||
|
endWidgetsForHost :: String -> Backend -> [TaffyIO Gtk.Widget]
|
||||||
|
endWidgetsForHost hostName backend =
|
||||||
|
let tray = sniTrayWidget
|
||||||
|
baseEndWidgets = [tray, audioWidget, networkWidget, mprisWidget]
|
||||||
|
-- Keep battery widgets visually *after* the tray (i.e. further to the right).
|
||||||
|
laptopEndWidgets =
|
||||||
|
batteryEndWidgets ++
|
||||||
|
[ tray
|
||||||
|
, audioWidget
|
||||||
|
, backlightWidget
|
||||||
|
, networkWidget
|
||||||
|
, mprisWidget
|
||||||
|
]
|
||||||
|
in if hostName `elem` laptopHosts
|
||||||
|
then laptopEndWidgets
|
||||||
|
else baseEndWidgets
|
||||||
|
|
||||||
|
mkSimpleTaffyConfig :: String -> Backend -> [FilePath] -> SimpleTaffyConfig
|
||||||
|
mkSimpleTaffyConfig hostName backend cssFiles =
|
||||||
|
defaultSimpleTaffyConfig
|
||||||
|
{ startWidgets = startWidgetsForBackend backend
|
||||||
|
, endWidgets = endWidgetsForHost hostName backend
|
||||||
|
, barPosition = Top
|
||||||
|
, widgetSpacing = 0
|
||||||
|
, barPadding = 4
|
||||||
|
, barHeight = ScreenRatio $ 1 / 36
|
||||||
|
, cssPaths = cssFiles
|
||||||
|
, centerWidgets = [clockWidget]
|
||||||
|
}
|
||||||
|
|
||||||
|
-- ** Entry Point
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
enableLogger "Graphics.UI.GIGtkStrut" DEBUG
|
enableLogger "Graphics.UI.GIGtkStrut" DEBUG
|
||||||
|
|
||||||
hostName <- getHostName
|
hostName <- getHostName
|
||||||
backend <- detectBackendRobust
|
backend <- detectBackendRobust
|
||||||
let relativeFiles = fromMaybe ["palette.css", "taffybar.css"] $ lookup hostName cssFilesByHostname
|
cssFiles <- mapM (getUserConfigFile "taffybar") (cssFilesForHost hostName)
|
||||||
cssFiles <- mapM (getUserConfigFile "taffybar") relativeFiles
|
|
||||||
|
|
||||||
let myCPU =
|
let simpleTaffyConfig = mkSimpleTaffyConfig hostName backend cssFiles
|
||||||
( deocrateWithSetClassAndBoxes "cpu" $
|
|
||||||
pollingGraphNew cpuCfg 5 cpuCallback
|
|
||||||
) :: TaffyIO Gtk.Widget
|
|
||||||
myMem =
|
|
||||||
( deocrateWithSetClassAndBoxes "mem" $
|
|
||||||
pollingGraphNew memCfg 5 memCallback
|
|
||||||
) :: TaffyIO Gtk.Widget
|
|
||||||
myNet =
|
|
||||||
( deocrateWithSetClassAndBoxes "net" $
|
|
||||||
networkGraphNew netCfg Nothing
|
|
||||||
) :: TaffyIO Gtk.Widget
|
|
||||||
myAudio = deocrateWithSetClassAndBoxes "audio" $
|
|
||||||
PulseAudio.pulseAudioLabelNew
|
|
||||||
myNetwork = deocrateWithSetClassAndBoxes "network" $
|
|
||||||
NetworkManager.networkManagerWifiLabelNew
|
|
||||||
myLayout = deocrateWithSetClassAndBoxes "layout" $
|
|
||||||
layoutNew defaultLayoutConfig
|
|
||||||
myWindows = deocrateWithSetClassAndBoxes "windows" $
|
|
||||||
windowsNew defaultWindowsConfig
|
|
||||||
myWorkspaces =
|
|
||||||
flip widgetSetClassGI "workspaces" =<<
|
|
||||||
X11Workspaces.workspacesNew X11Workspaces.defaultWorkspacesConfig
|
|
||||||
{ X11Workspaces.minIcons = 1
|
|
||||||
, X11Workspaces.getWindowIconPixbuf =
|
|
||||||
X11Workspaces.scaledWindowIconPixbufGetter $
|
|
||||||
X11Workspaces.getWindowIconPixbufFromChrome <|||>
|
|
||||||
X11Workspaces.unscaledDefaultGetWindowIconPixbuf <|||>
|
|
||||||
(\size _ -> fallbackIconPixbuf size)
|
|
||||||
, X11Workspaces.widgetGap = 0
|
|
||||||
, X11Workspaces.showWorkspaceFn = X11Workspaces.hideEmpty
|
|
||||||
, X11Workspaces.updateRateLimitMicroseconds = 100000
|
|
||||||
, X11Workspaces.labelSetter = workspaceNamesLabelSetter
|
|
||||||
, X11Workspaces.widgetBuilder = X11Workspaces.buildLabelOverlayController
|
|
||||||
}
|
|
||||||
myHyprWorkspaces =
|
|
||||||
flip widgetSetClassGI "workspaces" =<<
|
|
||||||
Hyprland.hyprlandWorkspacesNew Hyprland.defaultHyprlandWorkspacesConfig
|
|
||||||
{ Hyprland.widgetGap = 0
|
|
||||||
, Hyprland.minIcons = 1
|
|
||||||
-- Don't show Hyprland "special:*" workspaces.
|
|
||||||
, Hyprland.showWorkspaceFn =
|
|
||||||
(\ws -> Hyprland.workspaceState ws /= X11Workspaces.Empty &&
|
|
||||||
not (isSpecialHyprWorkspace ws))
|
|
||||||
, Hyprland.getWindowIconPixbuf =
|
|
||||||
hyprlandManualIconGetter <|||>
|
|
||||||
Hyprland.defaultHyprlandGetWindowIconPixbuf <|||>
|
|
||||||
hyprlandFallbackIcon
|
|
||||||
}
|
|
||||||
myClock = deocrateWithSetClassAndBoxes "clock" $
|
|
||||||
textClockNewWith
|
|
||||||
defaultClockConfig
|
|
||||||
{ clockUpdateStrategy = RoundedTargetInterval 60 0.0
|
|
||||||
, clockFormatString = "%a %b %_d, 🕑%I:%M %p"
|
|
||||||
}
|
|
||||||
myMpris =
|
|
||||||
mpris2NewWithConfig
|
|
||||||
MPRIS2Config
|
|
||||||
{ mprisWidgetWrapper = deocrateWithSetClassAndBoxes "mpris" . return
|
|
||||||
, updatePlayerWidget =
|
|
||||||
simplePlayerWidget
|
|
||||||
defaultPlayerConfig
|
|
||||||
{ setNowPlayingLabel = playingText 20 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
myBatteryIcon = deocrateWithSetClassAndBoxes "battery-icon" batteryIconNew
|
|
||||||
myBatteryText =
|
|
||||||
deocrateWithSetClassAndBoxes "battery-text" $ textBatteryNew "$percentage$%"
|
|
||||||
batteryWidgets = [ myBatteryIcon, myBatteryText ]
|
|
||||||
mySNITray = deocrateWithSetClassAndBoxes "sni-tray" $
|
|
||||||
case backend of
|
|
||||||
BackendWayland -> sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt
|
|
||||||
BackendX11 -> sniTrayNew
|
|
||||||
baseEndWidgets = [ myAudio, myNetwork, myMpris, mySNITray ]
|
|
||||||
laptopEndWidgets = batteryWidgets ++ baseEndWidgets
|
|
||||||
x11StartWidgets = [ myWorkspaces, myLayout, myWindows ]
|
|
||||||
hyprlandStartWidgets = [ myHyprWorkspaces ]
|
|
||||||
startWidgetsForBackend =
|
|
||||||
case backend of
|
|
||||||
BackendX11 -> x11StartWidgets
|
|
||||||
-- These Wayland widgets are Hyprland-specific.
|
|
||||||
BackendWayland -> hyprlandStartWidgets
|
|
||||||
baseConfig =
|
|
||||||
defaultSimpleTaffyConfig
|
|
||||||
{ startWidgets = startWidgetsForBackend
|
|
||||||
, endWidgets = baseEndWidgets
|
|
||||||
, barPosition = Top
|
|
||||||
, widgetSpacing = 0
|
|
||||||
, barPadding = 4
|
|
||||||
, barHeight = ScreenRatio $ 1 / 36
|
|
||||||
, cssPaths = cssFiles
|
|
||||||
, centerWidgets = [ myClock ]
|
|
||||||
}
|
|
||||||
hostOverrides =
|
|
||||||
[ ("uber-loaner", \cfg -> cfg { endWidgets = laptopEndWidgets })
|
|
||||||
, ("adell", \cfg -> cfg { endWidgets = laptopEndWidgets })
|
|
||||||
, ("stevie-nixos", \cfg -> cfg { endWidgets = laptopEndWidgets })
|
|
||||||
, ("strixi-minaj", \cfg -> cfg { endWidgets = laptopEndWidgets })
|
|
||||||
, ("jay-lenovo", \cfg -> cfg { endWidgets = laptopEndWidgets })
|
|
||||||
]
|
|
||||||
simpleTaffyConfig =
|
|
||||||
fromMaybe baseConfig $ ($ baseConfig) <$> lookup hostName hostOverrides
|
|
||||||
startTaffybar $
|
startTaffybar $
|
||||||
withLogServer $
|
withLogServer $
|
||||||
withToggleServer $
|
withToggleServer $
|
||||||
|
|||||||
@@ -1,203 +0,0 @@
|
|||||||
@define-color transparent rgba(0.0, 0.0, 0.0, 0.0);
|
|
||||||
@define-color white #FFFFFF;
|
|
||||||
@define-color black #000000;
|
|
||||||
@define-color taffy-blue #0c7cd5;
|
|
||||||
|
|
||||||
@define-color active-window-color @white;
|
|
||||||
@define-color urgent-window-color @taffy-blue;
|
|
||||||
@define-color font-color @white;
|
|
||||||
@define-color menu-background-color @white;
|
|
||||||
@define-color menu-font-color @black;
|
|
||||||
|
|
||||||
/* Top level styling */
|
|
||||||
|
|
||||||
.taffy-window * {
|
|
||||||
font-family: "Noto Sans", sans-serif;
|
|
||||||
font-size: 10pt;
|
|
||||||
color: @font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-box {
|
|
||||||
border-color: @white;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-pad {
|
|
||||||
padding: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contents {
|
|
||||||
padding: 1px;
|
|
||||||
transition: background-color .5s;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Workspaces styling */
|
|
||||||
|
|
||||||
.workspace-label {
|
|
||||||
padding-right: 3px;
|
|
||||||
padding-left: 2px;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active .contents {
|
|
||||||
background-color: rgba(0.0, 0.0, 0.0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.visible .contents {
|
|
||||||
background-color: rgba(0.0, 0.0, 0.0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container {
|
|
||||||
transition: opacity .5s, box-shadow .5s;
|
|
||||||
opacity: 1;
|
|
||||||
border-radius: 5px;
|
|
||||||
transition: background-color 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This gives space for the box-shadow (they look like underlines) that follow.
|
|
||||||
This will actually affect all widgets, (not just the workspace icons), but
|
|
||||||
that is what we want since we want the icons to look the same. */
|
|
||||||
.auto-size-image, .sni-tray {
|
|
||||||
padding: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.active {
|
|
||||||
background-color: rgba(255.0, 255.0, 255.0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.urgent {
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.inactive .window-icon {
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon-container.minimized .window-icon {
|
|
||||||
opacity: .3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.window-icon {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity .5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Button styling */
|
|
||||||
|
|
||||||
.taffy-window button {
|
|
||||||
all: initial;
|
|
||||||
background-color: @transparent;
|
|
||||||
border-width: 0px;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window button:checked, .taffy-window button:hover .Contents:hover {
|
|
||||||
box-shadow: inset 0 -3px @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Menu styling */
|
|
||||||
|
|
||||||
/* The ".taffy-window" prefixed selectors are needed because if they aren't present,
|
|
||||||
the top level .Taffybar selector takes precedence */
|
|
||||||
.taffy-window menuitem *, menuitem * {
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force an opaque background for menus, regardless of the system GTK theme. */
|
|
||||||
.taffy-window menu, menu,
|
|
||||||
.taffy-window menu.background, menu.background,
|
|
||||||
.taffy-window .menu, .menu,
|
|
||||||
.taffy-window .menu.background, .menu.background,
|
|
||||||
GtkMenu, GtkMenu.background {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.20);
|
|
||||||
padding: 4px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menu, menu {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some themes apply transparency to the menu's toplevel popup window. */
|
|
||||||
window.popup, window.popup.background,
|
|
||||||
window.menu, window.menu.background,
|
|
||||||
.menu, .menu.background {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup *, window.menu * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup decoration, window.menu decoration {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menuitem, menuitem {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem, GtkMenu menuitem, .menu menuitem {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menuitem:hover, menuitem:hover {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem:hover, GtkMenu menuitem:hover, .menu menuitem:hover {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.popup menuitem:hover *, window.menu menuitem:hover * {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu *, GtkMenu *, .menu * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu menuitem:hover *, GtkMenu menuitem:hover *, .menu menuitem:hover * {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.taffy-window menuitem:hover > label, menuitem:hover > label {
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some menus (notably a few StatusNotifierItem menus) are rendered as popovers
|
|
||||||
containing modelbuttons instead of menuitems. */
|
|
||||||
popover, popover.background, popover > contents {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.20);
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton, popover modelbutton * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton:hover {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton:hover > label {
|
|
||||||
color: @menu-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover * {
|
|
||||||
background-color: @menu-background-color;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
popover modelbutton:hover * {
|
|
||||||
background-color: @taffy-blue;
|
|
||||||
}
|
|
||||||
@@ -15,11 +15,8 @@ section: aliases
|
|||||||
imalison-desktop
|
imalison-desktop
|
||||||
imalison-home justin-bieber-creek
|
imalison-home justin-bieber-creek
|
||||||
controlling:
|
controlling:
|
||||||
uber-loaner
|
|
||||||
imalison-mpb-arch
|
imalison-mpb-arch
|
||||||
imalison-uber-loaner
|
|
||||||
Livien-MacbookAir
|
Livien-MacbookAir
|
||||||
kat-uber-loaner
|
|
||||||
Dean-PC
|
Dean-PC
|
||||||
imalison-mbp
|
imalison-mbp
|
||||||
strixi-minaj
|
strixi-minaj
|
||||||
|
|||||||
Reference in New Issue
Block a user