Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow changing the 'default' background color at runtime #238

Open
Ingvix opened this issue Oct 30, 2021 · 4 comments
Open

Allow changing the 'default' background color at runtime #238

Ingvix opened this issue Oct 30, 2021 · 4 comments

Comments

@Ingvix
Copy link

Ingvix commented Oct 30, 2021

I was surprised to notice that I couldn't change the background color of the whole bar at runtime, only the text background. I wished to change my bar color depending on which monitor has the focus but that doesn't seem to be possible. Would it be reasonable to implement this? I tried it myself but couldn't get it to work so far as this is my first time dabbling with xcb.

@Ingvix Ingvix changed the title Allow changing the 'default' background color Allow changing the 'default' background color at runtime Oct 30, 2021
@Ingvix
Copy link
Author

Ingvix commented Nov 4, 2021

And even if it's not implemented, I wouldn't mind any pointers making it for myself. I've tried doing it like this:

diff --git a/lemonbar.c b/lemonbar.c
index 4da59ee..6c4d3de 100644
--- a/lemonbar.c
+++ b/lemonbar.c
@@ -115,6 +115,14 @@ update_gc (void)
     xcb_change_gc(c, gc[GC_ATTR], XCB_GC_FOREGROUND, (const uint32_t []){ ugc.v });
 }

+void
+update_dbgc (void)
+{
+    for (monitor_t *mon = monhead; mon; mon = mon->next)
+        xcb_change_window_attributes(c, mon->window, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL,
+                (const uint32_t[]){dbgc.v, dbgc.v});
+}
+
 void
 fill_gradient (xcb_drawable_t d, int x, int y, int width, int height, rgba_t start, rgba_t stop)
 {
@@ -588,6 +596,7 @@ parse (char *text)
                         draw_lines(cur_mon, left_ep, right_ep - left_ep);
                         pos_x = 0; align = ALIGN_R;
                     } break;
+                    case 'b': dbgc = bgc = parse_color(p, &p, dbgc); update_dbgc(); update_gc(); break;

                     // Define input area.
                     case 'A': {

This results in the bar changing color on the next input line and not the current and somehow even this doesn't happen unless there's some pause between the inputs, as in echo "%{b#F00}foo"; sleep 1; echo "bar" | lemonbar -p changes the color on "bar" but echo "%{b#F00}foo"; echo "bar" | lemonbar -p doesn't change it at all. I have no clue why is this happening.

Also it would probably be wiser to use some additional variable to replace dbgc here to preserve the original background color but first I'd like to get this to work properly.

@Ingvix
Copy link
Author

Ingvix commented Nov 4, 2021

Another option would be to modify the B command's effect to continue from alignment to another painting the any gaps with the assigned background color, which would probably be more intuitive way of doing it, actually increasing the customization possibilities without increasing usage complexity.

@Ingvix
Copy link
Author

Ingvix commented Nov 4, 2021

I noticed the background is actually drawn on it everytime with fill_rect() before parsing the input line and therefore setting the window background doesn't do a thing visually. So that's one mystery solved.

Also it's stupid trying to drawing the color to every monitor's bar.

@Ingvix
Copy link
Author

Ingvix commented Nov 5, 2021

I ended up with this sort of solution that works for my use case. It works if used before any text to be drawn on the bar, otherwise it draws the rectangle on top of what's already drawn. "r" as an argument to "b" reverses the foreground and background color, so it's not really intuitive but since standalone "r" was already taken I just made it like this.

So clearly this is not something you'd want on the official release but if for the time being someone else without the proper knowhow wants to have this feature, they can just patch their build with this. I might not have enough motivation and/or knowhow to work on the good kind of implementation as described in #238 (comment) but I hope someone else will.

diff --git a/lemonbar.c b/lemonbar.c
index 4da59ee..975dbc4 100644
--- a/lemonbar.c
+++ b/lemonbar.c
@@ -603,6 +603,19 @@ parse (char *text)
                     case 'B': bgc = parse_color(p, &p, dbgc); update_gc(); break;
                     case 'F': fgc = parse_color(p, &p, dfgc); update_gc(); break;
                     case 'U': ugc = parse_color(p, &p, dugc); update_gc(); break;
+                    case 'b' : {
+                        if (*p == 'r') {
+                            rgba_t tmp = bgc;
+                            bgc = fgc;
+                            fgc = tmp;
+                            p += 1;
+                        } else {
+                            bgc = parse_color(p, &p, dbgc);
+                        }
+                        update_gc();
+                        fill_rect(cur_mon->pixmap, gc[GC_CLEAR], 0, 0, cur_mon->width, bh);
+                    } break;
+

                     // Set current monitor used for drawing.
                     case 'S': {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant