[dwm][patches][chargecolor] Added patch Charge Color - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 7ecaabe2191759e776f4f27bac2a3a28613cdb74
 (DIR) parent b5ccbe35e39163f944b05cc0c9237ff188117b5e
 (HTM) Author: elbachir-one <bachiralfa@gmail.com>
       Date:   Thu, 18 Sep 2025 13:03:36 +0100
       
       [dwm][patches][chargecolor] Added patch Charge Color
       
       Diffstat:
         A dwm.suckless.org/patches/chargecol… |     285 +++++++++++++++++++++++++++++++
         A dwm.suckless.org/patches/chargecol… |      18 ++++++++++++++++++
       
       2 files changed, 303 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/dwm.suckless.org/patches/chargecolor/dwm-chargecolor-20250918-2d2fd29.diff b/dwm.suckless.org/patches/chargecolor/dwm-chargecolor-20250918-2d2fd29.diff
       @@ -0,0 +1,285 @@
       +From 2d2fd29361c1e521fb74ef825d75135ad5da8482 Mon Sep 17 00:00:00 2001
       +From: elbachir-one <bachiralfa@gmail.com>
       +Date: Thu, 18 Sep 2025 12:32:15 +0100
       +Subject: [PATCH] Dynamically switches between predefined color schemes
       + depending on whether the AC is plugged in or unplugged
       +
       +---
       + config.def.h |  19 ++++----
       + dwm.c        | 133 ++++++++++++++++++++++++++++++++++++++++++++++++---
       + 2 files changed, 136 insertions(+), 16 deletions(-)
       +
       +diff --git a/config.def.h b/config.def.h
       +index 3836510..8075450 100644
       +--- a/config.def.h
       ++++ b/config.def.h
       +@@ -6,18 +6,17 @@ static const unsigned int snap      = 32;       /* snap pixel */
       + static const int showbar            = 1;        /* 0 means no bar */
       + static const int topbar             = 1;        /* 0 means bottom bar */
       + static const char *fonts[]          = { "monospace:size=10" };
       +-static const char dmenufont[]       = "monospace:size=10";
       +-static const char col_gray1[]       = "#222222";
       +-static const char col_gray2[]       = "#444444";
       +-static const char col_gray3[]       = "#bbbbbb";
       +-static const char col_gray4[]       = "#eeeeee";
       +-static const char col_cyan[]        = "#005577";
       +-static const char *colors[][3]      = {
       ++
       ++char *colors[][3] = {
       +         /*               fg         bg         border   */
       +-        [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
       +-        [SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },
       ++        [SchemeNorm] = { "#ffffff", "#222222", "#444444" },
       ++        [SchemeSel]  = { "#ffffff", "#005577", "#005577" },
       + };
       + 
       ++static const char **current_theme = NULL;
       ++static const char *blue[] = { "#ffffff", "#0E1C4A", "#3E54BD" };
       ++static const char *red[] = { "#ffffff", "#430B07", "#73493D" };
       ++
       + /* tagging */
       + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
       + 
       +@@ -58,7 +57,7 @@ static const Layout layouts[] = {
       + 
       + /* commands */
       + static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
       +-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
       ++static const char *dmenucmd[] = { "dmenu_run", NULL };
       + static const char *termcmd[]  = { "st", NULL };
       + 
       + static const Key keys[] = {
       +diff --git a/dwm.c b/dwm.c
       +index 4cf07eb..87c3ae0 100644
       +--- a/dwm.c
       ++++ b/dwm.c
       +@@ -22,14 +22,17 @@
       +  */
       + #include <errno.h>
       + #include <locale.h>
       ++#include <limits.h>
       + #include <signal.h>
       + #include <stdarg.h>
       + #include <stdio.h>
       + #include <stdlib.h>
       + #include <string.h>
       ++#include <dirent.h>
       + #include <unistd.h>
       + #include <sys/types.h>
       + #include <sys/wait.h>
       ++#include <pthread.h>
       + #include <X11/cursorfont.h>
       + #include <X11/keysym.h>
       + #include <X11/Xatom.h>
       +@@ -175,6 +178,7 @@ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
       + static void grabbuttons(Client *c, int focused);
       + static void grabkeys(void);
       + static void incnmaster(const Arg *arg);
       ++static int ischarging(void);
       + static void keypress(XEvent *e);
       + static void killclient(const Arg *arg);
       + static void manage(Window w, XWindowAttributes *wa);
       +@@ -215,6 +219,7 @@ static void toggleview(const Arg *arg);
       + static void unfocus(Client *c, int setfocus);
       + static void unmanage(Client *c, int destroyed);
       + static void unmapnotify(XEvent *e);
       ++static void updatecolors(void);
       + static void updatebarpos(Monitor *m);
       + static void updatebars(void);
       + static void updateclientlist(void);
       +@@ -240,6 +245,7 @@ static int screen;
       + static int sw, sh;           /* X display screen geometry width, height */
       + static int bh;               /* bar height */
       + static int lrpad;            /* sum of left and right padding for text */
       ++static int colorpipe[2];     /* pipe for notifying main thread about color changes */
       + static int (*xerrorxlib)(Display *, XErrorEvent *);
       + static unsigned int numlockmask = 0;
       + static void (*handler[LASTEvent]) (XEvent *) = {
       +@@ -493,6 +499,8 @@ cleanup(void)
       +         XSync(dpy, False);
       +         XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
       +         XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
       ++        close(colorpipe[0]);
       ++        close(colorpipe[1]);
       + }
       + 
       + void
       +@@ -983,6 +991,43 @@ incnmaster(const Arg *arg)
       +         arrange(selmon);
       + }
       + 
       ++int ischarging(void) {
       ++        const char *base = "/sys/class/power_supply/";
       ++        DIR *dir = opendir(base);
       ++        if (!dir) return 0;
       ++
       ++        struct dirent *entry;
       ++        char path[PATH_MAX];
       ++        FILE *f;
       ++        int status = 0;
       ++
       ++        while ((entry = readdir(dir))) {
       ++                if (entry->d_type != DT_DIR && entry->d_type != DT_LNK)
       ++                        continue;
       ++
       ++                snprintf(path, sizeof(path), "%s%s/type", base, entry->d_name);
       ++                f = fopen(path, "r");
       ++                if (!f) continue;
       ++
       ++                char type[32];
       ++                if (fgets(type, sizeof(type), f)) {
       ++                        if (strncmp(type, "Mains", 5) == 0) {
       ++                                fclose(f);
       ++                                snprintf(path, sizeof(path), "%s%s/online", base, entry->d_name);
       ++                                f = fopen(path, "r");
       ++                                if (!f) break;
       ++                                fscanf(f, "%d", &status);
       ++                                fclose(f);
       ++                                break;
       ++                        }
       ++                }
       ++                fclose(f);
       ++        }
       ++
       ++        closedir(dir);
       ++        return status;
       ++}
       ++
       + #ifdef XINERAMA
       + static int
       + isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
       +@@ -1382,11 +1427,36 @@ void
       + run(void)
       + {
       +         XEvent ev;
       +-        /* main event loop */
       +-        XSync(dpy, False);
       +-        while (running && !XNextEvent(dpy, &ev))
       +-                if (handler[ev.type])
       +-                        handler[ev.type](&ev); /* call handler */
       ++        int x11_fd = ConnectionNumber(dpy);
       ++        int maxfd = (colorpipe[0] > x11_fd) ? colorpipe[0] : x11_fd;
       ++
       ++        fd_set rfds;
       ++
       ++        while (running) {
       ++                FD_ZERO(&rfds);
       ++                FD_SET(x11_fd, &rfds);
       ++                FD_SET(colorpipe[0], &rfds);
       ++
       ++                if (select(maxfd + 1, &rfds, NULL, NULL, NULL) < 0) {
       ++                        if (errno == EINTR)
       ++                                continue;
       ++                        die("select failed");
       ++                }
       ++
       ++                if (FD_ISSET(colorpipe[0], &rfds)) {
       ++                        char buf[1];
       ++                        read(colorpipe[0], buf, 1);  /* clear pipe */
       ++                        updatecolors();              /* safe update in main thread */
       ++                }
       ++
       ++                if (FD_ISSET(x11_fd, &rfds)) {
       ++                        while (XPending(dpy)) {
       ++                                XNextEvent(dpy, &ev);
       ++                                if (handler[ev.type])
       ++                                        handler[ev.type](&ev);
       ++                        }
       ++                }
       ++        }
       + }
       + 
       + void
       +@@ -1582,10 +1652,13 @@ setup(void)
       +         cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
       +         cursor[CurResize] = drw_cur_create(drw, XC_sizing);
       +         cursor[CurMove] = drw_cur_create(drw, XC_fleur);
       ++        if (pipe(colorpipe) == -1) {
       ++                die("Failed to create pipe");
       ++        }
       +         /* init appearance */
       +         scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
       +         for (i = 0; i < LENGTH(colors); i++)
       +-                scheme[i] = drw_scm_create(drw, colors[i], 3);
       ++                scheme[i] = drw_scm_create(drw, (const char **)colors[i], 3);
       +         /* init bars */
       +         updatebars();
       +         updatestatus();
       +@@ -1711,6 +1784,21 @@ tile(Monitor *m)
       +                 }
       + }
       + 
       ++void *
       ++themechecker(void *arg) {
       ++        int last_status = -1;
       ++        for (;;) {
       ++                int charging = ischarging();
       ++                if (charging != last_status) {
       ++                        current_theme = charging ? blue : red;
       ++                        updatecolors();
       ++                        last_status = charging;
       ++                }
       ++                usleep(1000000);
       ++        }
       ++        return NULL;
       ++}
       ++
       + void
       + togglebar(const Arg *arg)
       + {
       +@@ -1814,6 +1902,34 @@ unmapnotify(XEvent *e)
       +         }
       + }
       + 
       ++void
       ++updatecolors(void) {
       ++        colors[SchemeNorm][0] = (char *)current_theme[0];
       ++        colors[SchemeNorm][1] = (char *)current_theme[1];
       ++        colors[SchemeNorm][2] = (char *)current_theme[1];
       ++
       ++        colors[SchemeSel][0] = (char *)current_theme[0];
       ++        colors[SchemeSel][1] = (char *)current_theme[2];
       ++        colors[SchemeSel][2] = (char *)current_theme[2];
       ++
       ++        for (int i = 0; i < LENGTH(colors); i++) {
       ++                if (scheme[i])
       ++                        free(scheme[i]);
       ++                scheme[i] = drw_scm_create(drw, (const char **)colors[i], 3);
       ++        }
       ++
       ++        for (Monitor *m = mons; m; m = m->next) {
       ++                drawbar(m);
       ++                arrange(m);
       ++
       ++                /* Update borders of all clients on this monitor */
       ++                for (Client *c = m->clients; c; c = c->next) {
       ++                        XSetWindowBorder(dpy, c->win,
       ++                                        scheme[c == m->sel ? SchemeSel : SchemeNorm][2].pixel);
       ++                }
       ++        }
       ++}
       ++
       + void
       + updatebars(void)
       + {
       +@@ -2152,12 +2268,17 @@ main(int argc, char *argv[])
       +                 die("dwm: cannot open display");
       +         checkotherwm();
       +         setup();
       ++
       ++        pthread_t theme_thread;
       ++        pthread_create(&theme_thread, NULL, themechecker, NULL);
       ++
       + #ifdef __OpenBSD__
       +         if (pledge("stdio rpath proc exec", NULL) == -1)
       +                 die("pledge");
       + #endif /* __OpenBSD__ */
       +         scan();
       +         run();
       ++        pthread_join(theme_thread, NULL);
       +         cleanup();
       +         XCloseDisplay(dpy);
       +         return EXIT_SUCCESS;
       +-- 
       +2.50.1
       +
 (DIR) diff --git a/dwm.suckless.org/patches/chargecolor/index.md b/dwm.suckless.org/patches/chargecolor/index.md
       @@ -0,0 +1,18 @@
       +Charge Color
       +============
       +
       +Description
       +-----------
       +The **Charge Color** patch for DWM dynamically switches between predefined
       +color schemes depending on whether the system is running on AC power or
       +battery. When you plug in or unplug the charger, DWM automatically updates the
       +bar, borders, and focused window colors to reflect the current power state.
       +
       +Download
       +--------
       +* [dwm-chargecolor-20250727-51f68f6.diff](dwm-chargecolor-20250727-51f68f6.diff)
       +
       +Authors
       +-------
       +* Nahyan Siddiqui - <nahyanl63@gmail.com>
       +* El Bachir - <bachiralfa@gmail.com>