dylanaraps / pywal

🎨 Generate and change color-schemes on the fly.
MIT License
8.32k stars 323 forks source link

Request: add xmonad instructions #172

Open JonathanReeve opened 6 years ago

JonathanReeve commented 6 years ago

I'm sure there's a way to use pywal with xmonad, but I don't know how that would be accomplished. Instructions in the wiki would be great.

dylanaraps commented 6 years ago

I’ve never used xmonad myself so these instructions will need to be written by an xmonad user using pywal.

Any takers?

ltpour commented 6 years ago

I use pywal with xmonad, but there are probably a lot more elegant ways to do it than what I hacked together. Basically I read the colors from .cache/wal/colors in xmonad.hs and use regexes to write them over the old ones in .xmobarrc. (You can't read them directly in .xmobarrc because it's not an actual Haskell file.) Here's my xmonad.hs for reference. You'll have to modify the regexes to match your xmobar configuration. Finally here's a slightly modified version of wal-set that reloads xmonad and trayer. If there's a less ugly and more universal solution I'd be interested in seeing it.

ahansen90 commented 6 years ago

I use pywal with xmonad. I don't actually know that we need separate instructions, because as far as I can tell, if behaves just like any other WM? I call wal in my .xinitrc (as per the setup instructions), and it functions as normal. The only "customization" I've done that is specific to xmonad is that I've added a keybind to execute "wal -i ~/wallpapers" to my xmonad.hs, but it's just like adding any other keybind in xmonad. XMonad is just using standard X stuff, so however you normally interact with X (whether it be xinitrc, xsession, etc.) will work here as well. If you have a specific issue I might be able to help, but I don't think separate documentation is necessary.

JonathanReeve commented 6 years ago

It's less about launching pywal using xmonad, and more about getting pywal to set xmonad colors. For instance, if you want to set the color of xmonad-drawn window borders using pywal, it'd be nice to know how to do this. Pywal seems to handle these settings with i3 quite nicely, but it's a little less clear on how it works with xmonad.

ltpour commented 6 years ago

In the config I linked above the getWalColors function reads the pywal colors into an array. Once you have the array, you can access individual colors with the !! notation, as in normalBorderColor = colors!!10, for example. Ignore the two ugly functions if you only need the colors for xmonad itself.

It would be difficult to add any general instructions in the wiki because there's so many different ways to write xmonad.hs. I don't think there even is an official default.

ahansen90 commented 6 years ago

Ah I see, my bad. I disabled the borders so long ago I forgot they were even a thing. I agree with @ltpour that it is difficult to have general purpose instructions since XMonad is configured using a full programming language (and thus has innumerable ways in which it can be configured), but I can perhaps give it a shot:

import System.Environment

import XMonad

-- Takes as input the name of an environment variable describing a color and a
-- xmonad configuration, and returns a new configuration with the normal border
-- color set to the color contained within the given environment
-- variable.
setNormalBorder :: String -> XConfig l -> IO (XConfig l)
setNormalBorder var conf = do
    color <- lookupEnv var
    return $ conf { normalBorderColor  = getColor color }
  where
    getColor (Just c)  = c
    getColor Nothing   = "#cccccc" -- Default to white if var is not found

This assumes the wal colors have been exported as environment variables. Probably can be improved, but this should get the job done.`

dylanaraps commented 6 years ago

pywal also exports the colors as json and yml. Does Haskell have a built in way of reading these files? If not we can add a new export format to make things easier.

ahansen90 commented 6 years ago

Not built in, but excellent libraries exist for doing just that, such as aeson. Perhaps that would be a better approach than using environment variables.

Naturally, Haskell can read the files as text by default, but you'd be better off using a json parsing library like the above.

dylanaraps commented 6 years ago

Can we export the colors as a haskell file which can be imported in your xmonad config?

Similar to the shell file which can be imported in shell scripts.

# Shell variables
# Generated by 'wal'
wallpaper='/home/black/Pictures/Wallpapers/wallhaven-295990.png'

# Special
background='#231d1a'
foreground='#c8c6c5'
cursor='#c8c6c5'

# Colors
color0='#231d1a'
color1='#ab615f'
color2='#c6937c'
color3='#c6a898'
color4='#8395aa'
color5='#a56a9d'
color6='#aa667c'
color7='#c8c6c5'
color8='#5a5553'
color9='#ab615f'
color10='#c6937c'
color11='#c6a898'
color12='#8395aa'
color13='#a56a9d'
color14='#aa667c'
color15='#c8c6c5'
ahansen90 commented 6 years ago

Yeah that's a pretty good idea actually. In fact, that shell file syntax will almost work, just change the single quotes to double quotes, and change the comment character to --. Then we can instruct people to place the file in the correct directory.

Modified example output file:

module Wal
    ( wallpaper
    , background, foreground, cursor
    , color0, color1, color2, color3, color4, color5, color6, color7
    , color8, color9, color10, color11, color12, color13, color14, color15
    ) where

-- Haskell bindings
-- Generated by 'wal'
wallpaper = "/home/black/Pictures/Wallpapers/wallhaven-295990.png"

-- Special
background = "#231d1a"
foreground = "#c8c6c5"
cursor = "#c8c6c5"

-- Colors
color0 = "#231d1a"
color1 = "#ab615f"
color2 = "#c6937c"
color3 = "#c6a898"
color4 = "#8395aa"
color5 = "#a56a9d"
color6 = "#aa667c"
color7 = "#c8c6c5"
color8 = "#5a5553"
color9 = "#ab615f"
color10 = "#c6937c"
color11 = "#c6a898"
color12 = "#8395aa"
color13 = "#a56a9d"
color14 = "#aa667c"
color15 = "#c8c6c5"

This could then be placed into .xmonad/lib and you would then put import Wal into your xmonad.hs.

I should add that to get XMonad to reload these colors, you would need to either restart xmonad using the default binding of mod-q, or by invoking xmonad --recompile && xmonad --restart in a shell.

sraysmith commented 5 years ago

I am an Xmonad user and would be happy to assist in resolving this ticket. I implemented the suggestion made by @asturtz2 and it will definitely work. However, some modification will need to be made to tell the pywal program to export the haskell format each time a new wal is set. Besides the export.py file, what other files will need to be modified?

mikenrafter commented 2 years ago

XMonad's code would likely need to be modified to include this support by default. However, not everyone wants this, so perhaps this code should just be given to the user when XMonad's detected, and the user runs a theme switch.

Also, everyone's XMobar config's going to differ, so having them write it all in a template file would be unreasonable.


My solution would be to use the environment-variable method, or to have XMo-nad/bar pull this information at launch from a file. That way, no recompile's needed each time.

Plus, everyone really should be using pure .hs files for XMobar configs anyway, so long as they're on XMonad.

samhh commented 2 years ago

A little while ago I wrote a module in my xmonad "app" to dynamically fetch and parse the JSON-encoded pywal colors. A bonus with this approach is that they're refreshed on reload rather than needing a full recompile, and given it's just an IO you could hook this into any other arbitrary dynamic setup.

https://github.com/samhh/dotfiles/blob/aa528503a2107e55e57e8bed84bf2b4f9bc6abd1/home/xmonad-samhh/lib/Color.hs