aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2021-11-06 00:50:47 -0600
committerJosh Rahm <joshuarahm@gmail.com>2021-11-06 00:50:47 -0600
commitd78c2c6f774f0b06b5914fcf99545a879ae8cc10 (patch)
treec1f98bb9e4b545207901c089dd305f063060542e
parentea44b017950cbab49a68959190ab0a859d45e7b1 (diff)
parent62eccced2d4a756b719dae9c25dc3859360608c2 (diff)
downloadrde-d78c2c6f774f0b06b5914fcf99545a879ae8cc10.tar.gz
rde-d78c2c6f774f0b06b5914fcf99545a879ae8cc10.tar.bz2
rde-d78c2c6f774f0b06b5914fcf99545a879ae8cc10.zip
Merge branch 'master' of github.com:jrahm/xmonad-jrahm
-rw-r--r--extras/HOME/.config/compton.conf4
-rw-r--r--extras/HOME/.xmobarrc24
-rwxr-xr-xextras/HOME/.xmonad/xmobar-weather101
-rw-r--r--src/Internal/CornerLayout.hs58
-rw-r--r--src/Internal/Keys.hs2
-rw-r--r--src/Internal/Layout.hs58
-rw-r--r--src/Internal/Lib.hs22
-rw-r--r--src/Internal/XMobarLog.hs20
8 files changed, 240 insertions, 49 deletions
diff --git a/extras/HOME/.config/compton.conf b/extras/HOME/.config/compton.conf
index 828d949..c669100 100644
--- a/extras/HOME/.config/compton.conf
+++ b/extras/HOME/.config/compton.conf
@@ -13,8 +13,8 @@ shadow-red = 0.0;
shadow-green = 0.0;
shadow-blue = 0.0;
-inactive-dim=0.1
-inactive-opacity=0.99
+inactive-dim=0.2
+inactive-opacity=0.98
shadow-exclude = [
# From the Ubuntu forums link ('screaminj3sus')
diff --git a/extras/HOME/.xmobarrc b/extras/HOME/.xmobarrc
index 52798af..e2a3e9f 100644
--- a/extras/HOME/.xmobarrc
+++ b/extras/HOME/.xmobarrc
@@ -1,12 +1,13 @@
Config
- { font = "xft:Monofur Nerd Font:size=15"
+ { font = "xft:Monofur Nerd Font:size=12"
, additionalFonts = [
"xft:Monofur bold Nerd Font:style=bold:size=12",
"xft:Monofur Nerd Font:size=9",
"xft:Monofur Nerd Font:size=9",
"xft:Monofur Nerd Font:size=6",
"xft:Monofur bold Nerd Font:size=15",
- "xft:Monofur Nerd Font:style=bold:size=10"
+ "xft:Monofur Nerd Font:style=bold:size=10",
+ "xft:Noto Sans Mono CJK JP:style=bold:size=10"
]
, borderColor = "black"
, border = FullBM -1
@@ -14,7 +15,7 @@ Config
, bgColor = "#000000"
, fgColor = "white"
, alpha = 220 -- default: 255
- , position = TopSize L 100 40
+ , position = TopSize L 100 50
, textOffset = -1 -- default: -1
, iconOffset = -1 -- default: -1
, lowerOnStart = True
@@ -31,7 +32,7 @@ Config
\</fc><fc=#a0a0a0> %date%</fc><fc=#404040> │ \
\</fc>%StdinReader%}<fn=6><fc=#909090>%time%</fc></fn>\
\{ %cpu% %memory% <fc=#404040>\
- \│</fc> %KLMO% <fc=#404040>│\
+ \│</fc> %weather% <fc=#404040>│\
\</fc> <fc=#a0a0a0>%mpris2%</fc> <fc=#404040>│ \
\</fc>%bluetooth%%bat% "
, commands = [
@@ -56,23 +57,10 @@ Config
"--normal", "#88ff88",
"--high", "#ff8888"
] 10,
- Run WeatherX "KLMO"
- [ ("clear", "<fc=#ddcf04>")
- , ("sunny", "<fc=#ddcf04>")
- , ("mostly clear", "<fc=#00a3c4>")
- , ("mostly sunny", "<fc=#ddcf04>")
- , ("partly sunny", "<fc=#ddcf04>")
- , ("fair", "<fc=#a0a0a0>🌑")
- , ("cloudy","<fc=#a0a0a0>摒")
- , ("overcast","<fc=#808080>")
- , ("partly cloudy", "<fc=#a0a0a0>杖")
- , ("mostly cloudy", "<fc=#808080>")
- , ("considerable cloudiness", "<fc=#a0a0a0>ﭽ")]
- ["--template", "<skyConditionS></fc><fn=3><fc=#a0a0a0> \
- \<tempF>°F</fc></fn>"] 360000,
Run Mpris2 "spotify" [
"-t", "<fc=#1aa54b></fc> <fn=3><title></fn>",
"--nastring", "<fc=#404040> </fc>"] 20,
+ Run Com ".xmonad/xmobar-weather" [] "weather" 9000,
Run Com ".xmonad/xmobar-logo" [] "logo" 0,
Run Com "uname" ["-r"] "uname" 0,
Run Com ".xmonad/xmobar-bluetooth" [] "bluetooth" 50,
diff --git a/extras/HOME/.xmonad/xmobar-weather b/extras/HOME/.xmonad/xmobar-weather
new file mode 100755
index 0000000..d9dc88b
--- /dev/null
+++ b/extras/HOME/.xmonad/xmobar-weather
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+
+use LWP::Simple;
+use Time::Local;
+use POSIX;
+
+$content = get("https://ipinfo.io");
+
+die "Unable to get IP info" unless defined $content;
+
+($city, $lat, $lon) =
+ ($content =~ m/.*"city":\s+"([^"]+)".*"loc":\s+"(-?[0-9.]+),(-?[0-9.]+).*"/ims);
+
+$content = get(
+ "https://api.sunrise-sunset.org/json?lat=$lat&lng=$lon&formatted=0");
+
+die "Unable to get sunrise/sunset data" unless defined $content;
+
+$sunrise_str=$content;
+$sunset_str=$content;
+$sunrise_str =~ s#.*"sunrise":"([^"]*)".*#\1#;
+$sunset_str =~ s#.*"sunset":"([^"]*)".*#\1#;
+$current_str=strftime "%Y-%m-%dT%H:%M:%S+00:00", gmtime();
+
+$content = get(
+ "https://tgftp.nws.noaa.gov/data/observations/metar/decoded/KLMO.TXT");
+
+die "Unable to get weather data" unless defined $content;
+
+$sky_conditions = $content;
+$sky_conditions =~ s#.*Sky conditions:\s+([^\n]+).*#\1#ims;
+$sky_conditions =~ s#\s#_#g;
+
+$wind = $content;
+$wind =~ s#.*Wind:\s+([^\n]+).*#\1#ims;
+($wind_direction, $wind_speed) =
+ ($wind =~ m/from the ([A-Z]+).*at (\d+) MPH.*/g);
+
+
+$temp = $content;
+$temp =~ s#.*Temperature:\s+(-?[0-9.]+) F.*#\1#ims;
+
+if ($current_str gt $sunrise_str and $current_str lt $sunset_str) {
+ $is_day = 1;
+} else {
+ $is_day = 0;
+}
+
+%directions = (
+ NE => "",
+ NNE => "",
+ ENE => "",
+ SE => "",
+ SSE => "",
+ ESE => "",
+ NW => "",
+ NNW => "",
+ WNW => "",
+ SW => "",
+ SSW => "",
+ WSW => "",
+ N => "",
+ S => "",
+ W => "",
+ E => "" );
+
+$dir=%directions{$wind_direction};
+
+%conditions_day = (
+ clear => "<fc=#ddcf04>",
+ sunny => "<fc=#ddcf04>",
+ mostly_clear => "<fc=#00a3c4>",
+ mostly_sunny => "<fc=#ddcf04>",
+ partly_sunny => "<fc=#ddcf04>",
+ fair => "<fc=#a0a0a0>🌑",
+ cloudy =>"<fc=#a0a0a0>摒",
+ overcast =>"<fc=#808080>",
+ partly_cloudy => "<fc=#a0a0a0>杖",
+ mostly_cloudy => "<fc=#808080>",
+ considerable_cloudiness => "<fc=#a0a0a0>ﭽ" );
+
+%conditions_night = (
+ clear => "<fc=#00a3c4>",
+ sunny => "<fc=#00a3c4>",
+ mostly_clear => "<fc=#00a3c4>",
+ mostly_sunny => "<fc=#00a3c4>",
+ partly_sunny => "<fc=#00a3c4>",
+ fair => "<fc=#808080>🌑",
+ cloudy =>"<fc=#808080>摒",
+ overcast =>"<fc=#404040>",
+ partly_cloudy => "<fc=#a0a0a0>",
+ mostly_cloudy => "<fc=#808080>",
+ considerable_cloudiness => "<fc=#a0a0a0>ﭽ" );
+
+if ($is_day) {
+ $conditions = %conditions_day{$sky_conditions};
+} else {
+ $conditions = %conditions_night{$sky_conditions};
+}
+
+printf("<fc=#a0a0a0><fn=3>$city</fn> <fn=3>$dir</fn> <fn=3>${wind_speed}</fn></fc> $conditions</fc><fn=3> <fc=#a0a0a0>%.0f°F</fc></fn>\n", $temp);
diff --git a/src/Internal/CornerLayout.hs b/src/Internal/CornerLayout.hs
new file mode 100644
index 0000000..10fbe5b
--- /dev/null
+++ b/src/Internal/CornerLayout.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
+-- Creates a layout, the "corner layout" that keeps the master window in the
+-- corner and the other windows go around it.
+module Internal.CornerLayout where
+
+import Data.Typeable (Typeable)
+import XMonad (LayoutClass(..), Rectangle(..), Resize(..), fromMessage)
+import qualified XMonad.StackSet as S
+
+data Corner a = Corner Rational Rational
+ deriving (Show, Typeable, Read)
+
+instance LayoutClass Corner a where
+ pureLayout (Corner frac _) screen@(Rectangle x y w h) ss =
+ let w' = floor $ fromIntegral w * frac
+ h' = floor $ fromIntegral h * frac
+ corner = Rectangle 0 0 w' h'
+ vertRect = Rectangle (fromIntegral w') 0 (w - w') h
+ horizRect = Rectangle 0 (fromIntegral h') w' (h - h')
+ ws = S.integrate ss
+
+ vn = (length ws - 1) `div` 2
+ hn = (length ws - 1) - vn
+ in
+ case ws of
+ [a] -> [(a, screen)]
+ [a, b] -> [
+ (a, Rectangle x y w' h),
+ (b, Rectangle (x + fromIntegral w') y (w - w') h)]
+ _ ->
+ zip ws $ map (
+ \(Rectangle x' y' w h) -> Rectangle (x + x') (y + y') w h) $
+ corner :
+ (splitVert vertRect vn) ++
+ (splitHoriz horizRect hn)
+
+ pureMessage (Corner frac delta) m = fmap resize (fromMessage m)
+ where
+ resize Shrink = Corner (frac - delta) delta
+ resize Expand = Corner (frac + delta) delta
+
+splitVert :: Rectangle -> Int -> [Rectangle]
+splitVert (Rectangle x y w h) i' =
+ map
+ (\i -> Rectangle x (y + fromIntegral (step * i)) w step)
+ [0 .. i - 1]
+ where
+ i = fromIntegral i'
+ step = h `div` i
+
+splitHoriz :: Rectangle -> Int -> [Rectangle]
+splitHoriz (Rectangle x y w h) i' =
+ map
+ (\i -> Rectangle (x + fromIntegral (step * i)) y step h)
+ [0 .. i - 1]
+ where
+ step = w `div` i
+ i = fromIntegral i'
diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs
index bc27750..d02e1f4 100644
--- a/src/Internal/Keys.hs
+++ b/src/Internal/Keys.hs
@@ -90,7 +90,7 @@ newKeys markContext =
, ((modm , xK_Return), windows W.swapMaster)
, ((modm, xK_j), sendMessage Shrink)
, ((modm, xK_k), sendMessage Expand)
- , ((modm .|. shiftMask, xK_r), (void $ spawn "gmrun"))
+ , ((modm .|. shiftMask, xK_r), sendMessage DoRotate)
, ((modm .|. mod1Mask, xK_l), (void $ spawn "xsecurelock"))
, ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock"))
, ((modm .|. shiftMask, xK_c), kill)
diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs
index cb8c19b..632e912 100644
--- a/src/Internal/Layout.hs
+++ b/src/Internal/Layout.hs
@@ -1,6 +1,7 @@
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
module Internal.Layout where
+import Internal.CornerLayout (Corner(..))
import Control.Arrow (second)
import XMonad.Hooks.ManageDocks
import XMonad.Layout.Circle
@@ -24,18 +25,20 @@ import qualified XMonad.StackSet as W
myLayout =
avoidStruts $
- ModifiedLayout (Zoomable False 0.05 0.05) $
- ModifiedLayout (Flippable False) $
- ModifiedLayout (HFlippable False) $
- spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $
- spiral (6/7) |||
- ModifyDescription TallDescriptionModifier (Tall 1 (3/100) (1/2)) |||
- ModifyDescription ThreeColDescMod (ThreeCol 1 (3/100) (1/2)) |||
- Full |||
- Grid |||
- Dishes 2 (1/6) |||
- (MosaicAlt M.empty :: MosaicAlt Window) |||
- (D.Dwindle D.R D.CW 1.5 1.1)
+ spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $
+ ModifiedLayout (Zoomable False 0.05 0.05) $
+ ModifiedLayout (Flippable False) $
+ ModifiedLayout (HFlippable False) $
+ ModifiedLayout (Rotateable False) $
+ spiral (6/7) |||
+ (Corner (3/4) (3/100) :: Corner Window) |||
+ ModifyDescription TallDescriptionModifier (Tall 1 (3/100) (1/2)) |||
+ ModifyDescription ThreeColDescMod (ThreeCol 1 (3/100) (1/2)) |||
+ Full |||
+ Grid |||
+ Dishes 2 (1/6) |||
+ (MosaicAlt M.empty :: MosaicAlt Window) |||
+ (D.Dwindle D.R D.CW 1.5 1.1)
data ModifyDescription m l a = ModifyDescription m (l a)
deriving (Show, Read)
@@ -90,10 +93,15 @@ data Flippable a = Flippable Bool -- True if flipped
data HFlippable a = HFlippable Bool -- True if flipped
deriving (Show, Read)
+data Rotateable a = Rotateable Bool -- True if rotated
+ deriving (Show, Read)
+
data FlipLayout = FlipLayout deriving (Typeable)
data HFlipLayout = HFlipLayout deriving (Typeable)
+data DoRotate = DoRotate deriving (Typeable)
+
data Zoomable a = Zoomable Bool Float Float -- True if zooming in on the focused window.
deriving (Show, Read)
@@ -111,6 +119,32 @@ instance Message HFlipLayout where
instance Message ZoomModifier where
+instance Message DoRotate where
+
+instance (Eq a) => LayoutModifier Rotateable a where
+ pureModifier (Rotateable rotate) (Rectangle _ _ sw sh) _ returned =
+ if rotate
+ then (map (second (scaleRect . mirrorRect)) returned, Nothing)
+ else (returned, Nothing)
+ where
+ scaleRect (Rectangle x y w h) =
+ Rectangle (x * fi sw `div` fi sh)
+ (y * fi sh `div` fi sw)
+ (w * sw `div` sh)
+ (h * sh `div` sw)
+
+ fi = fromIntegral
+
+
+ pureMess (Rotateable rot) mess =
+ fmap (\(DoRotate) -> Rotateable (not rot)) (fromMessage mess)
+
+ modifyDescription (Rotateable rot) underlying =
+ let descr = description underlying in
+ if rot
+ then descr ++ " Rotated"
+ else descr
+
instance (Eq a) => LayoutModifier Flippable a where
pureModifier (Flippable flip) (Rectangle sx _ sw _) stack returned =
if flip
diff --git a/src/Internal/Lib.hs b/src/Internal/Lib.hs
index feb5f26..3ba1eca 100644
--- a/src/Internal/Lib.hs
+++ b/src/Internal/Lib.hs
@@ -21,6 +21,9 @@ import XMonad hiding (workspaces, Screen)
import XMonad.StackSet hiding (filter, focus)
import qualified Data.Map as Map
import Internal.DMenu
+import Data.Ord (comparing)
+
+import qualified XMonad.StackSet as S
type WorkspaceName = Char
newtype Selector = Selector (forall a. (Eq a) => a -> [a] -> a)
@@ -31,6 +34,23 @@ instance XPrompt WinPrompt where
showXPrompt _ = "[Window] "
commandToComplete _ = id
+data WorkspaceState = Current | Hidden | Visible
+
+-- Returns all the workspaces that are either visible, current or Hidden but
+-- have windows and that workspace's state.
+--
+-- In other words, filters out workspaces that have no windows and are not
+-- visible.
+--
+-- This function will sort the result by the workspace tag.
+getPopulatedWorkspaces ::
+ (Ord i) => S.StackSet i l a sid sd -> [(WorkspaceState, S.Workspace i l a)]
+getPopulatedWorkspaces (S.StackSet (S.Screen cur _ _) vis hi _) =
+ sortBy (comparing (tag . snd)) $
+ mapMaybe (\w@(S.Workspace _ _ s) -> fmap (const (Hidden, w)) s) hi ++
+ map (\(S.Screen w _ _) -> (Visible, w)) vis ++
+ [(Current, cur)]
+
getHorizontallyOrderedScreens ::
StackSet wid l a ScreenId ScreenDetail ->
[Screen wid l a ScreenId ScreenDetail]
@@ -91,7 +111,7 @@ getString = runQuery $ do
relativeWorkspaceShift :: Selector -> X ()
relativeWorkspaceShift (Selector selector) = do
windows $ \ss ->
- let tags = sort $ (tag <$> filter (isJust . stack) (workspaces ss))
+ let tags = sort $ (tag . snd <$> getPopulatedWorkspaces ss)
from = tag $ workspace $ current ss
to = selector from tags
in greedyView to ss
diff --git a/src/Internal/XMobarLog.hs b/src/Internal/XMobarLog.hs
index d0ff8f8..c0aa2a7 100644
--- a/src/Internal/XMobarLog.hs
+++ b/src/Internal/XMobarLog.hs
@@ -1,5 +1,6 @@
module Internal.XMobarLog ( XMobarLog, spawnXMobar, xMobarLogHook ) where
+import Control.Arrow (second)
import Control.Monad (forM_)
import Control.Monad.Writer (tell, execWriter)
import Data.List (sortBy)
@@ -10,12 +11,11 @@ import System.IO (Handle, hSetEncoding, hPutStrLn, utf8)
import XMonad.Util.NamedWindows (getName)
import XMonad.Util.Run (spawnPipe)
import XMonad (X)
+import Internal.Lib (getPopulatedWorkspaces, WorkspaceState(..))
import qualified XMonad as X
import qualified XMonad.StackSet as S
-data WorkspaceState = Current | Hidden | Visible
-
data XMobarLog = XMobarLog Handle
-- The log hook for XMobar. This is a custom log hook that does not use any
@@ -39,19 +39,19 @@ xMobarLogHook (XMobarLog xmproc) = do
winset <- X.gets X.windowset
title <- maybe (pure "") (fmap show . getName) . S.peek $ winset
- let wss = getWorkspaces winset
+ let wss = getPopulatedWorkspaces winset
X.liftIO $ do
hPutStrLn xmproc $ trunc 80 $ execWriter $ do
tell layoutXpm
tell $ "<fc=#404040> │ </fc>"
- forM_ wss $ \(t, name) -> do
+ forM_ wss $ \(t, ws) -> do
case t of
Current -> tell "<fn=1><fc=#ff8888>"
Visible -> tell "<fn=6><fc=#8888ff>"
Hidden -> tell "<fn=2><fc=#888888>"
- tell name
+ tell (S.tag ws)
tell " </fc></fn>"
tell $ "<fc=#404040>│ </fc><fc=#a0a0a0><fn=3>"
@@ -76,13 +76,3 @@ trunc amt str = reverse $ trunc' False amt str []
0 -> trunc' False 0 as acc
3 -> trunc' False 0 as ("..." ++ acc)
_ -> trunc' False (amt - 1) as (a : acc)
-
--- Returns all the workspaces with a stack on them and if that workspace is
--- Visible, Current or Hidden.
-getWorkspaces :: (Ord i) => S.StackSet i l a sid sd -> [(WorkspaceState, i)]
-getWorkspaces (S.StackSet (S.Screen cur _ _) vis hi _) =
- sortBy (comparing snd) $
- mapMaybe (\(a, S.Workspace t _ s) -> fmap (const (a, t)) s) $
- map (\w -> (Hidden, w)) hi ++
- map (\(S.Screen w _ _) -> (Visible, w)) vis ++
- [(Current, cur)]