diff options
Diffstat (limited to 'accounts/gkleen@sif/taffybar')
| -rw-r--r-- | accounts/gkleen@sif/taffybar/default.nix | 2 | ||||
| -rw-r--r-- | accounts/gkleen@sif/taffybar/gkleen-sif-taffybar.cabal | 31 | ||||
| -rw-r--r-- | accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/Clock.hs | 111 | ||||
| -rw-r--r-- | accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/TooltipBattery.hs | 101 | ||||
| -rw-r--r-- | accounts/gkleen@sif/taffybar/src/taffybar.hs | 83 | ||||
| -rw-r--r-- | accounts/gkleen@sif/taffybar/taffybar.css | 146 |
6 files changed, 474 insertions, 0 deletions
diff --git a/accounts/gkleen@sif/taffybar/default.nix b/accounts/gkleen@sif/taffybar/default.nix new file mode 100644 index 00000000..98366d8f --- /dev/null +++ b/accounts/gkleen@sif/taffybar/default.nix | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | { haskellPackages ? (import <nixpkgs> {}).haskellPackages }: | ||
| 2 | haskellPackages.callCabal2nix "gkleen-sif-taffybar" ./. {} | ||
diff --git a/accounts/gkleen@sif/taffybar/gkleen-sif-taffybar.cabal b/accounts/gkleen@sif/taffybar/gkleen-sif-taffybar.cabal new file mode 100644 index 00000000..7f56dece --- /dev/null +++ b/accounts/gkleen@sif/taffybar/gkleen-sif-taffybar.cabal | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | name: gkleen-sif-taffybar | ||
| 2 | version: 0.0.0 | ||
| 3 | build-type: Simple | ||
| 4 | cabal-version: >=1.10 | ||
| 5 | |||
| 6 | data-files: taffybar.css | ||
| 7 | |||
| 8 | executable taffybar | ||
| 9 | hs-source-dirs: src | ||
| 10 | main-is: taffybar.hs | ||
| 11 | ghc-options: -threaded -rtsopts -with-rtsopts=-N -O2 -Wall | ||
| 12 | build-depends: base | ||
| 13 | , containers | ||
| 14 | , directory | ||
| 15 | , filepath | ||
| 16 | , gtk3 | ||
| 17 | , taffybar | ||
| 18 | , X11>=1.8 | ||
| 19 | , transformers | ||
| 20 | , gi-gtk | ||
| 21 | , time, time-locale-compat | ||
| 22 | , text | ||
| 23 | , HStringTemplate | ||
| 24 | , gtk-sni-tray | ||
| 25 | other-modules: Paths_gkleen_sif_taffybar | ||
| 26 | , System.Taffybar.Widget.Clock | ||
| 27 | , System.Taffybar.Widget.TooltipBattery | ||
| 28 | default-language: Haskell2010 | ||
| 29 | default-extensions: ScopedTypeVariables | ||
| 30 | , LambdaCase | ||
| 31 | , NamedFieldPuns \ No newline at end of file | ||
diff --git a/accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/Clock.hs b/accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/Clock.hs new file mode 100644 index 00000000..e8dc480f --- /dev/null +++ b/accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/Clock.hs | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | {-# LANGUAGE OverloadedStrings #-} | ||
| 2 | module System.Taffybar.Widget.Clock | ||
| 3 | ( textClockNew | ||
| 4 | , textClockNewWith | ||
| 5 | , defaultClockConfig | ||
| 6 | , ClockConfig(..) | ||
| 7 | , ClockUpdateStrategy(..) | ||
| 8 | ) where | ||
| 9 | |||
| 10 | import Control.Monad.IO.Class | ||
| 11 | import Data.Maybe | ||
| 12 | import qualified Data.Text as T | ||
| 13 | import qualified Data.Time.Clock as Clock | ||
| 14 | import Data.Time.Format | ||
| 15 | import Data.Time.LocalTime | ||
| 16 | import qualified Data.Time.Locale.Compat as L | ||
| 17 | import GI.Gtk | ||
| 18 | import System.Taffybar.Widget.Generic.PollingLabel | ||
| 19 | |||
| 20 | type ClockFormat = L.TimeLocale -> ZonedTime -> T.Text | ||
| 21 | |||
| 22 | -- | Create the widget. I recommend passing @Nothing@ for the TimeLocale | ||
| 23 | -- parameter. The format string can include Pango markup | ||
| 24 | -- (<http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>). | ||
| 25 | textClockNew :: | ||
| 26 | MonadIO m => Maybe L.TimeLocale -> ClockFormat -> Double -> m GI.Gtk.Widget | ||
| 27 | textClockNew userLocale format interval = | ||
| 28 | textClockNewWith cfg | ||
| 29 | where | ||
| 30 | cfg = defaultClockConfig { clockTimeLocale = userLocale | ||
| 31 | , clockFormat = format | ||
| 32 | , clockUpdateStrategy = ConstantInterval interval | ||
| 33 | } | ||
| 34 | |||
| 35 | data ClockUpdateStrategy | ||
| 36 | = ConstantInterval Double | ||
| 37 | | RoundedTargetInterval Int Double | ||
| 38 | deriving (Eq, Ord, Show) | ||
| 39 | |||
| 40 | data ClockConfig = ClockConfig | ||
| 41 | { clockTimeZone :: Maybe TimeZone | ||
| 42 | , clockTimeLocale :: Maybe L.TimeLocale | ||
| 43 | , clockFormat :: ClockFormat | ||
| 44 | , clockUpdateStrategy :: ClockUpdateStrategy | ||
| 45 | } | ||
| 46 | |||
| 47 | -- | A clock configuration that defaults to the current locale | ||
| 48 | defaultClockConfig :: ClockConfig | ||
| 49 | defaultClockConfig = ClockConfig | ||
| 50 | { clockTimeZone = Nothing | ||
| 51 | , clockTimeLocale = Nothing | ||
| 52 | , clockFormat = \locale zonedTime -> T.pack $ formatTime locale "%a %b %_d %r" zonedTime | ||
| 53 | , clockUpdateStrategy = RoundedTargetInterval 5 0.0 | ||
| 54 | } | ||
| 55 | |||
| 56 | systemGetTZ :: IO TimeZone | ||
| 57 | systemGetTZ = getCurrentTimeZone | ||
| 58 | |||
| 59 | -- | A configurable text-based clock widget. It currently allows for | ||
| 60 | -- a configurable time zone through the 'ClockConfig'. | ||
| 61 | -- | ||
| 62 | -- See also 'textClockNew'. | ||
| 63 | textClockNewWith :: MonadIO m => ClockConfig -> m Widget | ||
| 64 | textClockNewWith ClockConfig | ||
| 65 | { clockTimeZone = userZone | ||
| 66 | , clockTimeLocale = userLocale | ||
| 67 | , clockFormat = format | ||
| 68 | , clockUpdateStrategy = updateStrategy | ||
| 69 | } = liftIO $ do | ||
| 70 | let getTZ = maybe systemGetTZ return userZone | ||
| 71 | locale = fromMaybe L.defaultTimeLocale userLocale | ||
| 72 | |||
| 73 | let getUserZonedTime = | ||
| 74 | utcToZonedTime <$> getTZ <*> Clock.getCurrentTime | ||
| 75 | |||
| 76 | doTimeFormat = format locale | ||
| 77 | |||
| 78 | getRoundedTimeAndNextTarget = do | ||
| 79 | zonedTime <- getUserZonedTime | ||
| 80 | return $ case updateStrategy of | ||
| 81 | ConstantInterval interval -> | ||
| 82 | (doTimeFormat zonedTime, Nothing, interval) | ||
| 83 | RoundedTargetInterval roundSeconds offset -> | ||
| 84 | let roundSecondsDiffTime = fromIntegral roundSeconds | ||
| 85 | addTheRound = addLocalTime roundSecondsDiffTime | ||
| 86 | localTime = zonedTimeToLocalTime zonedTime | ||
| 87 | ourLocalTimeOfDay = localTimeOfDay localTime | ||
| 88 | seconds = round $ todSec ourLocalTimeOfDay | ||
| 89 | secondsFactor = seconds `div` roundSeconds | ||
| 90 | displaySeconds = secondsFactor * roundSeconds | ||
| 91 | baseLocalTimeOfDay = | ||
| 92 | ourLocalTimeOfDay { todSec = fromIntegral displaySeconds } | ||
| 93 | ourLocalTime = | ||
| 94 | localTime { localTimeOfDay = baseLocalTimeOfDay } | ||
| 95 | roundedLocalTime = | ||
| 96 | if seconds `mod` roundSeconds > roundSeconds `div` 2 | ||
| 97 | then addTheRound ourLocalTime | ||
| 98 | else ourLocalTime | ||
| 99 | roundedZonedTime = | ||
| 100 | zonedTime { zonedTimeToLocalTime = roundedLocalTime } | ||
| 101 | nextTarget = addTheRound ourLocalTime | ||
| 102 | amountToWait = realToFrac $ diffLocalTime nextTarget localTime | ||
| 103 | in (doTimeFormat roundedZonedTime, Nothing, amountToWait - offset) | ||
| 104 | |||
| 105 | label <- pollingLabelWithVariableDelay getRoundedTimeAndNextTarget | ||
| 106 | ebox <- eventBoxNew | ||
| 107 | containerAdd ebox label | ||
| 108 | eventBoxSetVisibleWindow ebox False | ||
| 109 | widgetShowAll ebox | ||
| 110 | toWidget ebox | ||
| 111 | |||
diff --git a/accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/TooltipBattery.hs b/accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/TooltipBattery.hs new file mode 100644 index 00000000..9dc52774 --- /dev/null +++ b/accounts/gkleen@sif/taffybar/src/System/Taffybar/Widget/TooltipBattery.hs | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | {-# LANGUAGE OverloadedStrings #-} | ||
| 2 | {-# LANGUAGE ScopedTypeVariables #-} | ||
| 3 | module System.Taffybar.Widget.TooltipBattery ( batteryIconTooltipNew ) where | ||
| 4 | |||
| 5 | import Control.Applicative | ||
| 6 | import Control.Monad | ||
| 7 | import Control.Monad.IO.Class | ||
| 8 | import Control.Monad.Trans.Reader | ||
| 9 | import Data.Int (Int64) | ||
| 10 | import qualified Data.Text as T | ||
| 11 | import GI.Gtk | ||
| 12 | import Prelude | ||
| 13 | import StatusNotifier.Tray (scalePixbufToSize) | ||
| 14 | import System.Taffybar.Context | ||
| 15 | import System.Taffybar.Information.Battery | ||
| 16 | import System.Taffybar.Util | ||
| 17 | import System.Taffybar.Widget.Generic.AutoSizeImage | ||
| 18 | import System.Taffybar.Widget.Generic.ChannelWidget | ||
| 19 | import Text.Printf | ||
| 20 | import Text.StringTemplate | ||
| 21 | import Data.Function ((&)) | ||
| 22 | |||
| 23 | -- | Just the battery info that will be used for display (this makes combining | ||
| 24 | -- several easier). | ||
| 25 | data BatteryWidgetInfo = BWI | ||
| 26 | { seconds :: Maybe Int64 | ||
| 27 | , percent :: Double | ||
| 28 | , status :: String | ||
| 29 | , rate :: Maybe Double | ||
| 30 | } deriving (Eq, Show) | ||
| 31 | |||
| 32 | -- | Format a duration expressed as seconds to hours and minutes | ||
| 33 | formatDuration :: Int64 -> String | ||
| 34 | formatDuration secs = let minutes, hours, minutes' :: Int64 | ||
| 35 | minutes = secs `div` 60 | ||
| 36 | (hours, minutes') = minutes `divMod` 60 | ||
| 37 | in printf "%02d:%02d" hours minutes' | ||
| 38 | |||
| 39 | getBatteryWidgetInfo :: BatteryInfo -> BatteryWidgetInfo | ||
| 40 | getBatteryWidgetInfo info = | ||
| 41 | let battPctNum :: Double | ||
| 42 | battPctNum = batteryPercentage info | ||
| 43 | battTime :: Maybe Int64 | ||
| 44 | battTime = | ||
| 45 | case batteryState info of | ||
| 46 | BatteryStateCharging -> Just $ batteryTimeToFull info | ||
| 47 | BatteryStateDischarging -> Just $ batteryTimeToEmpty info | ||
| 48 | _ -> Nothing | ||
| 49 | battStatus :: String | ||
| 50 | battStatus = | ||
| 51 | case batteryState info of | ||
| 52 | BatteryStateCharging -> "↑" | ||
| 53 | BatteryStateDischarging -> "↓" | ||
| 54 | BatteryStateEmpty -> "⤓" | ||
| 55 | BatteryStateFullyCharged -> "⤒" | ||
| 56 | _ -> "?" | ||
| 57 | battRate :: Maybe Double | ||
| 58 | battRate | rawRate < 0.1 = Nothing | ||
| 59 | | otherwise = Just rawRate | ||
| 60 | where rawRate = batteryEnergyRate info | ||
| 61 | in BWI{ seconds = battTime, percent = battPctNum, status = battStatus, rate = battRate } | ||
| 62 | |||
| 63 | -- | Given (maybe summarized) battery info and format: provides the string to display | ||
| 64 | formatBattInfo :: BatteryWidgetInfo -> String -> T.Text | ||
| 65 | formatBattInfo info fmt = | ||
| 66 | let tpl = newSTMP fmt | ||
| 67 | tpl' = tpl | ||
| 68 | & setManyAttrib [ ("percentage", printf "%.0f" $ percent info) | ||
| 69 | , ("status", status info) | ||
| 70 | ] | ||
| 71 | & setManyAttrib [ ("time", formatDuration <$> seconds info) | ||
| 72 | , ("rate", printf "%.0f" <$> rate info) | ||
| 73 | ] | ||
| 74 | in render tpl' | ||
| 75 | |||
| 76 | themeLoadFlags :: [IconLookupFlags] | ||
| 77 | themeLoadFlags = [IconLookupFlagsGenericFallback, IconLookupFlagsUseBuiltin] | ||
| 78 | |||
| 79 | batteryIconTooltipNew :: String -> TaffyIO Widget | ||
| 80 | batteryIconTooltipNew format = do | ||
| 81 | DisplayBatteryChanVar (chan, _) <- setupDisplayBatteryChanVar ["IconName", "State", "Percentage", "TimeToFull", "TimeToEmpty", "EnergyRate"] | ||
| 82 | ctx <- ask | ||
| 83 | liftIO $ do | ||
| 84 | image <- imageNew | ||
| 85 | styleCtx <- widgetGetStyleContext =<< toWidget image | ||
| 86 | defaultTheme <- iconThemeGetDefault | ||
| 87 | let getCurrentBatteryIconNameStringTooltip = do | ||
| 88 | info <- runReaderT getDisplayBatteryInfo ctx | ||
| 89 | let iconNameString = T.pack $ batteryIconName info | ||
| 90 | tooltip = formatBattInfo (getBatteryWidgetInfo info) format | ||
| 91 | return (iconNameString, tooltip) | ||
| 92 | extractPixbuf info = | ||
| 93 | fst <$> iconInfoLoadSymbolicForContext info styleCtx | ||
| 94 | setIconForSize size = do | ||
| 95 | (name, tooltip) <- getCurrentBatteryIconNameStringTooltip | ||
| 96 | widgetSetTooltipMarkup image $ Just tooltip | ||
| 97 | iconThemeLookupIcon defaultTheme name size themeLoadFlags >>= | ||
| 98 | traverse extractPixbuf >>= | ||
| 99 | traverse (scalePixbufToSize size OrientationHorizontal) | ||
| 100 | updateImage <- autoSizeImage image setIconForSize OrientationHorizontal | ||
| 101 | toWidget =<< channelWidgetNew image chan (const $ postGUIASync updateImage) | ||
diff --git a/accounts/gkleen@sif/taffybar/src/taffybar.hs b/accounts/gkleen@sif/taffybar/src/taffybar.hs new file mode 100644 index 00000000..dd713ea7 --- /dev/null +++ b/accounts/gkleen@sif/taffybar/src/taffybar.hs | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | {-# LANGUAGE OverloadedStrings #-} | ||
| 2 | |||
| 3 | module Main where | ||
| 4 | |||
| 5 | import System.Taffybar (startTaffybar) | ||
| 6 | import System.Taffybar.Context (TaffybarConfig(..)) | ||
| 7 | import System.Taffybar.Hooks | ||
| 8 | import System.Taffybar.SimpleConfig hiding (SimpleTaffyConfig(cssPath)) | ||
| 9 | import System.Taffybar.Widget | ||
| 10 | import qualified System.Taffybar.Widget.Clock as MyClock | ||
| 11 | import System.Taffybar.Widget.TooltipBattery | ||
| 12 | |||
| 13 | import Data.Time.Format | ||
| 14 | import Data.Time.LocalTime | ||
| 15 | import Data.Time.Calendar.WeekDate | ||
| 16 | |||
| 17 | import qualified Data.Text as T | ||
| 18 | |||
| 19 | import Control.Exception (SomeException, try) | ||
| 20 | import Control.Monad.Trans.Reader (mapReaderT) | ||
| 21 | |||
| 22 | import Paths_gkleen_sif_taffybar | ||
| 23 | |||
| 24 | |||
| 25 | main :: IO () | ||
| 26 | main = do | ||
| 27 | myCssPath <- getDataFileName "taffybar.css" | ||
| 28 | startTaffybar exampleTaffybarConfig{ cssPath = Just myCssPath } | ||
| 29 | |||
| 30 | |||
| 31 | exampleTaffybarConfig :: TaffybarConfig | ||
| 32 | exampleTaffybarConfig = | ||
| 33 | let myWorkspacesConfig = | ||
| 34 | defaultWorkspacesConfig | ||
| 35 | { maxIcons = Just 0 | ||
| 36 | , widgetGap = 7 | ||
| 37 | , showWorkspaceFn = \case | ||
| 38 | -- Workspace{ workspaceState = Empty } -> False | ||
| 39 | Workspace{ workspaceName } | workspaceName == "NSP" -> False | ||
| 40 | _other -> True | ||
| 41 | , getWindowIconPixbuf = \i d -> either (\(_ :: SomeException) -> Nothing) id <$> mapReaderT try (defaultGetWindowIconPixbuf i d) | ||
| 42 | } | ||
| 43 | workspaces = workspacesNew myWorkspacesConfig | ||
| 44 | clock = MyClock.textClockNewWith MyClock.defaultClockConfig | ||
| 45 | { MyClock.clockUpdateStrategy = MyClock.RoundedTargetInterval 1 0.0 | ||
| 46 | , MyClock.clockFormat = \tl zt@ZonedTime{ zonedTimeToLocalTime = LocalTime{ localDay } } | ||
| 47 | -> let date = formatTime tl "%Y-%m-%d" localDay | ||
| 48 | weekdate = "W" <> show2 woy <> "-" <> show dow | ||
| 49 | where (_, woy, dow) = toWeekDate localDay | ||
| 50 | show2 :: Int -> String | ||
| 51 | show2 x = replicate (2 - length s) '0' ++ s | ||
| 52 | where s = show x | ||
| 53 | time = formatTime tl "%H:%M:%S%Ez" zt | ||
| 54 | in T.intercalate " " $ map T.pack [date, weekdate, time] | ||
| 55 | } | ||
| 56 | layout = layoutNew defaultLayoutConfig | ||
| 57 | windowsW = windowsNew defaultWindowsConfig | ||
| 58 | { getMenuLabel = truncatedGetMenuLabel 80 | ||
| 59 | , getActiveLabel = truncatedGetActiveLabel 80 | ||
| 60 | } | ||
| 61 | worktime = commandRunnerNew 150 "worktime" [] "worktime" | ||
| 62 | worktimeToday = commandRunnerNew 150 "worktime" ["today"] "worktime today" | ||
| 63 | -- See https://github.com/taffybar/gtk-sni-tray#statusnotifierwatcher | ||
| 64 | -- for a better way to set up the sni tray | ||
| 65 | -- tray = sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt | ||
| 66 | tray = sniTrayNew | ||
| 67 | myConfig = defaultSimpleTaffyConfig | ||
| 68 | { startWidgets = | ||
| 69 | workspaces : map (>>= buildContentsBox) [ layout, windowsW ] | ||
| 70 | , endWidgets = map (>>= buildContentsBox) $ reverse | ||
| 71 | -- , mpris2New | ||
| 72 | [ worktime, worktimeToday | ||
| 73 | , clock | ||
| 74 | , tray | ||
| 75 | , batteryIconTooltipNew "$status$ $percentage$%$if(time)$$if(rate)$ ($rate$W $time$)$else$ ($time$)$endif$$elseif(rate)$ ($rate$W)$endif$" | ||
| 76 | ] | ||
| 77 | , barPosition = Top | ||
| 78 | , barPadding = 2 | ||
| 79 | , barHeight = 28 | ||
| 80 | , widgetSpacing = 10 | ||
| 81 | } | ||
| 82 | in withBatteryRefresh $ withLogServer $ | ||
| 83 | withToggleServer $ toTaffyConfig myConfig | ||
diff --git a/accounts/gkleen@sif/taffybar/taffybar.css b/accounts/gkleen@sif/taffybar/taffybar.css new file mode 100644 index 00000000..7a297465 --- /dev/null +++ b/accounts/gkleen@sif/taffybar/taffybar.css | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | @define-color transparent rgba(0.0, 0.0, 0.0, 0.0); | ||
| 2 | @define-color white #808080; | ||
| 3 | @define-color gray #202020; | ||
| 4 | @define-color green #008000; | ||
| 5 | @define-color yellow #808000; | ||
| 6 | @define-color blue #000080; | ||
| 7 | @define-color red #800000; | ||
| 8 | @define-color black #000000; | ||
| 9 | /* @define-color taffy-blue #0c7cd5; */ | ||
| 10 | @define-color taffy-blue @blue; | ||
| 11 | |||
| 12 | @define-color active-window-color @white; | ||
| 13 | @define-color urgent-window-color @taffy-blue; | ||
| 14 | @define-color font-color @white; | ||
| 15 | @define-color menu-background-color @black; | ||
| 16 | @define-color menu-font-color @white; | ||
| 17 | |||
| 18 | /* Top level styling */ | ||
| 19 | |||
| 20 | .taffy-window * { | ||
| 21 | /* | ||
| 22 | This removes any existing styling from UI elements. Taffybar will not | ||
| 23 | cohere with your gtk theme. | ||
| 24 | */ | ||
| 25 | all: unset; | ||
| 26 | |||
| 27 | font-family: "Fira Sans", sans-serif; | ||
| 28 | font-size: 21px; | ||
| 29 | color: @font-color; | ||
| 30 | } | ||
| 31 | |||
| 32 | .taffy-box { | ||
| 33 | /* border-radius: 10px; */ | ||
| 34 | background-color: @black; | ||
| 35 | } | ||
| 36 | |||
| 37 | .inner-pad { | ||
| 38 | /* padding-bottom: 5px; */ | ||
| 39 | /* padding-top: 5px; */ | ||
| 40 | padding-left: 2px; | ||
| 41 | padding-right: 2px; | ||
| 42 | } | ||
| 43 | |||
| 44 | .contents { | ||
| 45 | /* padding-bottom: 4px; */ | ||
| 46 | /* padding-top: 4px; */ | ||
| 47 | padding-right: 2px; | ||
| 48 | padding-left: 2px; | ||
| 49 | transition: background-color .5s; | ||
| 50 | border-radius: 5px; | ||
| 51 | } | ||
| 52 | |||
| 53 | /* Workspaces styling */ | ||
| 54 | |||
| 55 | .workspace-label { | ||
| 56 | padding-right: 3px; | ||
| 57 | padding-left: 2px; | ||
| 58 | font-size: 21px; | ||
| 59 | } | ||
| 60 | |||
| 61 | .workspace-label.active { | ||
| 62 | color: @green; | ||
| 63 | } | ||
| 64 | .workspace-label.visible { | ||
| 65 | color: @yellow; | ||
| 66 | } | ||
| 67 | .workspace-label.empty { | ||
| 68 | color: @gray; | ||
| 69 | } | ||
| 70 | .workspace-label.urgent { | ||
| 71 | color: @red; | ||
| 72 | } | ||
| 73 | |||
| 74 | .active .contents { | ||
| 75 | background-color: rgba(0.0, 0.0, 0.0, 0.5); | ||
| 76 | } | ||
| 77 | |||
| 78 | .visible .contents { | ||
| 79 | background-color: rgba(0.0, 0.0, 0.0, 0.2); | ||
| 80 | } | ||
| 81 | |||
| 82 | .window-icon-container { | ||
| 83 | transition: opacity .5s, box-shadow .5s; | ||
| 84 | opacity: 1; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* This gives space for the box-shadow (they look like underlines) that follow. | ||
| 88 | This will actually affect all widgets, (not just the workspace icons), but | ||
| 89 | that is what we want since we want the icons to look the same. */ | ||
| 90 | .auto-size-image, .sni-tray { | ||
| 91 | padding-top: 3px; | ||
| 92 | padding-bottom: 3px; | ||
| 93 | } | ||
| 94 | |||
| 95 | .window-icon-container.active { | ||
| 96 | box-shadow: inset 0 -3px @white; | ||
| 97 | } | ||
| 98 | |||
| 99 | .window-icon-container.urgent { | ||
| 100 | box-shadow: inset 0 -3px @urgent-window-color; | ||
| 101 | } | ||
| 102 | |||
| 103 | .window-icon-container.inactive .window-icon { | ||
| 104 | padding: 0px; | ||
| 105 | } | ||
| 106 | |||
| 107 | .window-icon-container.minimized .window-icon { | ||
| 108 | opacity: .3; | ||
| 109 | } | ||
| 110 | |||
| 111 | .window-icon { | ||
| 112 | opacity: 1; | ||
| 113 | transition: opacity .5s; | ||
| 114 | } | ||
| 115 | |||
| 116 | /* Button styling */ | ||
| 117 | |||
| 118 | button { | ||
| 119 | background-color: @transparent; | ||
| 120 | border-width: 0px; | ||
| 121 | border-radius: 0px; | ||
| 122 | } | ||
| 123 | |||
| 124 | button:checked, button:hover .Contents:hover { | ||
| 125 | box-shadow: inset 0 -3px @taffy-blue; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* Menu styling */ | ||
| 129 | |||
| 130 | /* The ".taffy-window" prefixed selectors are needed because if they aren't present, | ||
| 131 | the top level .Taffybar selector takes precedence */ | ||
| 132 | .taffy-window menuitem *, menuitem * { | ||
| 133 | color: @menu-font-color; | ||
| 134 | } | ||
| 135 | |||
| 136 | .taffy-window menuitem, menuitem { | ||
| 137 | background-color: @menu-background-color; | ||
| 138 | } | ||
| 139 | |||
| 140 | .taffy-window menuitem:hover, menuitem:hover { | ||
| 141 | background-color: @taffy-blue; | ||
| 142 | } | ||
| 143 | |||
| 144 | .taffy-window menuitem:hover > label, menuitem:hover > label { | ||
| 145 | color: @white; | ||
| 146 | } | ||
