sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 7ecaabe2191759e776f4f27bac2a3a28613cdb74
parent b5ccbe35e39163f944b05cc0c9237ff188117b5e
Author: elbachir-one <bachiralfa@gmail.com>
Date:   Thu, 18 Sep 2025 13:03:36 +0100

[dwm][patches][chargecolor] Added patch Charge Color

Diffstat:
Adwm.suckless.org/patches/chargecolor/dwm-chargecolor-20250918-2d2fd29.diff | 285+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/chargecolor/index.md | 18++++++++++++++++++
2 files changed, 303 insertions(+), 0 deletions(-)

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 + 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>