dunst-project / dunst

Lightweight and customizable notification daemon
https://dunst-project.org
Other
4.53k stars 340 forks source link

Xresource colors #357

Closed tadly closed 1 day ago

tadly commented 7 years ago

It's probably pretty obvious what I mean solely by the title. To put it into a complete sentence though, I'd love to use/reference Xresource colors within the config.

I use pywal to generate a color pallet and, for the time being, use a wrapper script to start dunst with all the colors applied. This I'd like to get rid of.

WhyNotHugo commented 7 years ago

Dunst is not currently Xorg specific, so this would actually mean maintaining two configuration sources, with one being compile-time optional. 😕

tadly commented 7 years ago

facepalms I even remember reading about dunst not being xorg specific in some other issues I'm following. Totally forgot about that.

As a developer myself I see how "ugly" this could/can get... ...as a user I want a central point to configure my color palette without hacking.

Let the brainstrom begin! So far... nothing.

ghost commented 7 years ago

Hi I don't usually comment on dunst issues, I just follow them because I use and really like dunst! Are the Xresource colors the ones from something like: /usr/share/X11/rgb.txt And do you mean the color names? This would make sense to support since these color names (though X11 specific are also used in the web as well). Here is a function I use for that...

#include <X11/Xlib.h>
///etc...
std::string x_color_from_name(const char *colorName){
        Display *dpy;
        Colormap map;
        int scr;
        XColor rgb, nearest_rgb;
        dpy = XOpenDisplay(NULL);
        scr = XDefaultScreen(dpy);
        map = DefaultColormap(dpy, scr);
        XLookupColor(dpy, map, colorName, &rgb, &nearest_rgb);
        int red = (int)rgb.red>>8;
        int green = (int)rgb.green>>8;
        int blue = (int)rgb.blue>>8;
        char tmp[8];
        std::snprintf(tmp, sizeof(tmp), "#%02x%02x%02x", red, green, blue);
        std::string output = tmp;
        return output;
}
ghost commented 7 years ago

Just search for Xlibs in the makefile, and set some define and then wrap the function in that define

#ifdef X_EXISTS
//function from above converted to c string
#endif
tsipinakis commented 7 years ago

And do you mean the color names? This would make sense to support since these color names (though X11 specific are also used in the web as well).

No, @Tadly is talking about a completely different thing entirely - having the ability to customize the colors from the .Xresources file, you're talking about X11 color value support.

I am against using X11 to parse color values because as mentioned above dunst is not X11 specific and I'm currently trying to decouple the X code from the rest of the drawing stuff and making it so that specific color values only work when X is used is going to be a functionality and documentation mess.


On the actual topic of the issue, adding support for Xresources parsing, I agree with @hobarrera that having 2 configuration sources with one optional is ugly but a work around would be to make it so that setting the colors to a certain value parses it from Xresources. E.g.

background = "$xresources.bg"
Dunst.bg: #0000ff

Opinions on this?

tadly commented 7 years ago

@Israel- What @tsipinakis said :) I was talking about the colors one maintains within the .Xresources file.

I like the proposed idea. That's about all I can say :)

From what I can tell, background and foreground is what's typically used so we'd have:

Dunst.background: #0000ff
Dunst.foreground: #0000ff

Additional colors within the Xresources are typically configured using wildcards and should therefor be easily accessible too (depending on the implementation of course)

*color1: #0000ff
*.color1: #0000ff
...
ghost commented 7 years ago

@Tadly @tsipinakis I see, in that case I would have to agree with @tsipinakis we already have the dunst config file which handles things like that. Are you wanting to move color config out of there into an Xresources file? For your solo use case you should write a simple script that generates your dunst config... use a

while read LINE
do
  case $LINE in
    Dunst.background:*)BACKGROUND="${LINE/*:}";;
## ETC
    *);;
  esac
done < "$X_RESOURCE_FILE_NAME"

Then you can either use another loop like that or the ever useful sed Then drop the chmod +x script into your startup (which depends on if you use WM or DE) And once it gets working nicely put it into the contrib :smile:

tadly commented 7 years ago

@Israel- Sorry it took so long. I do already have a workaround as mentioned in the OP.

This was just something that would make live a little easier and as i3, polybar etc. do support reading Xresource values, I thought it might be cool to have dunst support it as well, not remembering that dunst isn't Xorg specific.

nhatzHK commented 6 years ago

@Tadly do you mind dropping your workaround here :)

I was trying to achieve the same and just came in the issue list to find this discussion. I would propose to make commands usable in the config file. For example, I could have the following:

frame_color = `xrdb -query all | grep *colorN | awk '{print $x}'`
# or
frame_color = $(same as above)

This wouldn't require to have two different config bases since the user would be reponsib;e to feed the colors to dunst, at the same time he'd be easier for him to do so.

I don't really know how bad/good giving users the ability to execute arbitrary commands in the config is.

tadly commented 6 years ago

@nhatzHK That workaround is just a script starting dunst with cli flags but here you go :)

#!/usr/bin/env bash

source "${HOME}/.cache/wal/colors.sh"

/usr/bin/dunst \
    -lb "${color0:-#F0F0F0}" \
    -nb "${color0:-#F0F0F0}" \
    -cb "${color0:-#F0F0F0}" \
    -lf "${color15:=#000000}" \
    -bf "${color15:=#000000}" \
    -cf "${color15:=#000000}" \
    -nf "${color15:=#000000}"
tsipinakis commented 6 years ago

I don't really know how bad/good giving users the ability to execute arbitrary commands in the config is.

I think it's worth considering as an idea, if anything it'll allow for some more customization in the config. I'm also not sure of the security implications of this though.

That workaround is just a script starting dunst with cli flags but here you go :)

In case you weren't aware this workaround might go away soon as these flags are deprecated, see #328

tadly commented 6 years ago

In case you weren't aware this workaround might go away soon as these flags are deprecated, see #328

awwww you're killing me! ':D Guess I'll then have to start generating a config file or something. Thanks for letting me know though :)

bebehei commented 6 years ago

I don't really know how bad/good giving users the ability to execute arbitrary commands in the config is.

I think it's worth considering as an idea, if anything it'll allow for some more customization in the config. I'm also not sure of the security implications of this though.

What about having the ability to use config from STDIN instead?

Like this:

#!/bin/sh

get_color(){
echo '#hex_val' and so on.
}

dunst -config - <<-END
[global]
frame_color = $(get_color frame)

END

You're only limited in shell and you don't have to implement any spooky things. It suffices implementing to read STDIN, when filename is -.


Anyway, I pose another question: There is wayland showing up on the horizon and with Ubuntu 17.10/18.04 it gets much thrust. Is it actually worth implementing such an X11 specific feature?

samuelhnrq commented 6 years ago

Sorry for necro-posting this issue, but I really belive this would be a killer feature, and I don't agree we should pass on this just because of wayland, X11 isn't going to magically disappear just because wayland becomes more stable... And besides, instead of limiting this to parsing xrdb values, but also parsing values from the config itself... Like polybar config system, which is amazing, and is also TOML like, just has the amazing ${} syntax which has some kind of parsing engine to replace values, no arbitrary code.

WhyNotHugo commented 6 years ago

@samosaara I understand that Xorg won't be disappearing any time soon, but given that dunst support both Xorg and wayland means it can't just support Xorg, hence, the need to keep around the current configuration mechanism.

The problem with adding Xresources-specific code, it is that is adds a lot of complexity (and basically duplicates the amount of related code) of reading configuration. This isn't just an extra effort to implement, but also to maintain and debug in future.

bebehei commented 6 years ago

@samosaara You're not necro-posting an issue. We value any reasoned opinion on this. @WhyNotHugo has given a very good explanation, why we're reluctant to add any X11 specific stuff (and wayland specific either).

I wonder, why nobody has answered my proposal to add a configuration file via STDIN, which gives you the full power of a shell, without implementing any spooky stuff inside of dunst.

samuelhnrq commented 6 years ago

Well I belive not supporting xrdb is simply not suporting Xorg fully, just partially, I understand trying to stay display server agnostic, but you have to understand each one of them has their own particularities.

And I actually took the time to study your claim about complexity and I simply belive that's not the case, at all whatsoever, since it's already being used anyway, XLib provides a bunch of methods to easily deal with X resources (here). It's literally a single method call (having the display instance) to load the current Xrdb and also single other method to read any value. And about 20 lines over here to add such method calls some simple parsing, (of values starting with $ for example) and read it from the X resources database.

If you don't want to implement it because it would feel like functionality is missing from the wayland side, sure, (even though, doesn't Xwayland implement this anyway?) but

adds a lot of complexity (and basically duplicates the amount of related adds a lot of complexity (and basically duplicates the amount of related code)

Is not the case.

tsipinakis commented 6 years ago

And about 20 lines over here to add such method calls some simple parsing, (of values starting with $ for example) and read it from the X resources database.

That wouldn't work, dunst hasn't even connected to the X server at that point, and we need to have read the config to have everything we need to know to call x_setup(). While it could be broken down into smaller parts it complicates the code quite a bit and furthermore it adds a direct dependency of X11 specific code to the config parser which will make a compile-time option to disable X11 harder to implement once wayland support has been added.

nhatzHK commented 6 years ago

What about giving the ability to read the content of another file inside the dunst config file. For X you have files where certain things are stored, and you can get that information with xrdb(I think I said this earlier). It doesn't have to be X or Wayland specific since you're just reading a file. Something like that:

frame_color = xrdb -query all | grep *color7 | awk '{print $x}'

Now the only thing to implement would be detecting certain characters (in this case ``) and treating what is inside them specially (in this case as a shell command).

That would also work if you want to specifiy values from STDIN since other programs (like cat) already support - as an identifier to read from STDIN. Polyabr does it differently (but in a more X specific way) with background = ${xrdb:color7}, you probably won't like that one for the reasons you have stated earlier.

Anyway I think having more flexibility in the config file would be a good thing. For example I use the same config files on several machines and I rely on small things like that to make them work without any trouble on any machine. Also if you change your colourscheme for example, not having to go through each config file to update each colour is a plus imo.

I don't know how much complexity this would add since I'm not familiar with the codebase. I do believe it's a good (portable) alternative.

WhyNotHugo commented 6 years ago

FWIW, can't you write a scripts that reads Xresources values, and outputs a valid dunst configuration file? It sounds a lot simpler, and doesn't require any changes to dunst itself.

samuelhnrq commented 6 years ago

Hugo idea is sound, and once again, there is a method to do that in Xlib XrmDatabase XrmGetFileDatabase(char *filename); but that's kinda shady because the person could have a non default xresources file name, multiple of em, etc, etc. So, I think smarter still is just to parse xrdb's output that does all that heavy lifting for us.

bebehei commented 6 years ago

Hi all. There is #525 created by @lulivi, which claims to fix this issue. From my side, the code looks very good, but I haven't tested the functionality of the script. I'm not using Xresource files. If anyone of you is interested to speedup the resolution of this issue, please test the PR #525 and give feedback there. You'd do a favor to all of us. Thanks in advance.

donovanglover commented 5 years ago

For pywal users: I solved this problem by writing my dunstrc as a user template file and symlinking the resulting cache file to ~/.config/dunst/dunstrc.

This is a newer feature of pywal that wasn't available when this issue was opened.

ghost commented 5 years ago

Hey @GloverDonovan Do you mind showing an example?

douglasrizzo commented 4 years ago

I'll go ahead and share my hacky way to get color information from Xresources, since no one seems to do what I do.

I keep the main dunst configuration in its config file and I set the colors in command-line args. I query X for the colors using a small program I found called xgetres.

dunst -config ~/.config/dunst/dunstrc \
  -cb "$(xgetres background)" \
  -lb "$(xgetres background)" \
  -nb "$(xgetres background)" \
  -cf "$(xgetres foreground)" \
  -lf "$(xgetres foreground)" \
  -nf "$(xgetres foreground)" \
  -bf "$(xgetres foreground)" \
  -frame_color "$(xgetres foreground)"

The downside of this method is that, if dunst is started by a program that calls notify-send before I start it manually, it will start with default colors and I have to restart it manually.

lulivi commented 4 years ago

@annata83 here is an example template! Take care if you have the default comments:

    # The geometry of the window:
    #   [{{width}}]x{{height}}[+/-{{x}}+/-{{y}}]

you have to scape the {width} with double {} for pywal to work properly.

balajsra commented 3 years ago

I'll go ahead and share my hacky way to get color information from Xresources, since no one seems to do what I do.

I keep the main dunst configuration in its config file and I set the colors in command-line args. I query X for the colors using a small program I found called xgetres.

dunst -config ~/.config/dunst/dunstrc \
  -cb "$(xgetres background)" \
  -lb "$(xgetres background)" \
  -nb "$(xgetres background)" \
  -cf "$(xgetres foreground)" \
  -lf "$(xgetres foreground)" \
  -nf "$(xgetres foreground)" \
  -bf "$(xgetres foreground)" \
  -frame_color "$(xgetres foreground)"

The downside of this method is that, if dunst is started by a program that calls notify-send before I start it manually, it will start with default colors and I have to restart it manually.

Thank you! I was able to modify this slightly to get around the manual restart issue you mentioned.

The first issue is that any previous dunst instances need to be stopped.

The second issue is that reading the Xresource values while running dunst introduced a delay that would allow another program to start dunst again (with notify-send) between when it was killed and attempting to restart.

My version gets around the issue by getting the Xresources values first, then killing any dunst instances and starting it again at the same time. See below.

#!/bin/bash

# Get values from Xresources
config=~/.config/dunst/dunstrc
geometry_x=$(xgetres dunst.geometry-x)
geometry_y=$(xgetres dunst.geometry-y)
separator_height=$(xgetres dunst.sep-height)
padding=$(xgetres dunst.padding)
horizontal_padding=$(xgetres dunst.horiz-padding)
max_icon_size=$(xgetres dunst.max-icon-size)
frame_width=$(xgetres dunst.frame-width)
lb=$(xgetres dunst.low-background)
lf=$(xgetres dunst.low-foreground)
lfr=$(xgetres dunst.low-frame)
nb=$(xgetres dunst.normal-background)
nf=$(xgetres dunst.normal-foreground)
nfr=$(xgetres dunst.normal-frame)
cb=$(xgetres dunst.critical-background)
cf=$(xgetres dunst.critical-foreground)
cfr=$(xgetres dunst.critical-frame)

# Kill and running dunst instances and start
killall dunst;/usr/bin/dunst -config $config \
    -geometry "0x0-$geometry_x+$geometry_y" \
    -separator_height "$separator_height" \
    -padding "$padding" \
    -horizontal_padding "$horizontal_padding" \
    -max_icon_size "$max_icon_size" \
    -frame_width "$frame_width" \
    -lb "$lb" \
    -lf "$lf" \
    -lfr "$lfr" \
    -nb "$nb" \
    -nf "$nf" \
    -nfr "$nfr" \
    -cb "$cb" \
    -cf "$cf" \
    -cfr "$cfr"
bynect commented 1 day ago

I will close this since we have no current plan to add Xresource builtin support. However, if you want to use the values from Xresource you could usea script that changes the dunstrc (like the contrib/dunst_xr_theme_changer.sh) and do dunstctl reload to dynamically change the colors.

NOTE: in the future environment variable support may be added, so stay tuned