From d6b0c95b91d17aae1a9ceb62528ccb08dfca8cb2 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Fri, 12 Nov 2021 16:11:59 +0500 Subject: [PATCH] Move status to separate module --- Makefile | 2 +- atoms.c | 2 +- atoms.h | 2 +- datetime.c | 35 ++-------------- datetime.h | 3 -- dwm.c | 33 +++++++++++---- status.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++ status.h | 15 +++++++ 8 files changed, 167 insertions(+), 45 deletions(-) create mode 100644 status.c create mode 100644 status.h diff --git a/Makefile b/Makefile index 37574f7..9fb636e 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = atoms.c datetime.c drw.c dwm.c util.c +SRC = atoms.c datetime.c drw.c dwm.c status.c util.c OBJ = ${SRC:.c=.o} all: options dwm diff --git a/atoms.c b/atoms.c index caf9046..3867912 100644 --- a/atoms.c +++ b/atoms.c @@ -26,7 +26,7 @@ Atoms atoms_create(Display *const dpy) atoms->netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); atoms->netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); atoms->netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); - atoms->netatom[NetDateTime] = XInternAtom(dpy, "_NET_DATE_TIME", False); + atoms->netatom[NetStatusUpdate] = XInternAtom(dpy, "_NET_STATUS_UPDATE", False); atoms->xatom[Manager] = XInternAtom(dpy, "MANAGER", False); atoms->xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); diff --git a/atoms.h b/atoms.h index 54d1685..67a0144 100644 --- a/atoms.h +++ b/atoms.h @@ -8,7 +8,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDialog, - NetClientList, NetDateTime, NetLast, + NetClientList, NetStatusUpdate, NetLast, }; /* Xembed atoms */ diff --git a/datetime.c b/datetime.c index d253ce7..a41b418 100644 --- a/datetime.c +++ b/datetime.c @@ -1,15 +1,17 @@ #include "datetime.h" #include "atoms.h" +#include "status.h" #include #include #include #include -#include #define BUFFER_SIZE 32 +static void datetime_lock(); +static void datetime_unlock(); static void *run(void *vargp); static const char *const default_text = "date & time"; @@ -17,9 +19,6 @@ static const char *const default_text = "date & time"; static pthread_mutex_t mutex; static bool running = false; -static Display *display = None; -static Atoms atoms = NULL; - static pthread_t thread; static bool thread_created = false; @@ -35,11 +34,6 @@ void datetime_unlock() pthread_mutex_unlock(&mutex); } -const char *datetime_get() -{ - return buffer; -} - bool datetime_start() { datetime_lock(); @@ -49,9 +43,6 @@ bool datetime_start() running = true; strcpy(buffer, default_text); - if ((display = XOpenDisplay(NULL)) == NULL) return false; - if ((atoms = atoms_create(display)) == NULL) return false; - thread_created = pthread_create(&thread, NULL, run, NULL) == 0; datetime_unlock(); @@ -67,8 +58,6 @@ void datetime_stop() running = false; if (thread_created) pthread_join(thread, NULL); - if (atoms != NULL) atoms_destroy(atoms); - if (display != None) XCloseDisplay(display); datetime_unlock(); } @@ -85,23 +74,7 @@ void *run(void *vargp) strftime(buffer, sizeof(buffer), "%a, %e %b %Y, %H:%M:%S", time_info); datetime_unlock(); - XEvent event; - memset(&event, 0, sizeof(event)); - event.xclient.type = ClientMessage; - event.xclient.serial = 0; - event.xclient.send_event = True; - event.xclient.display = display; - event.xclient.window = DefaultRootWindow(display); - event.xclient.message_type = atoms->netatom[NetDateTime]; - event.xclient.format = 32; - XSendEvent( - display, - event.xclient.window, - False, - SubstructureRedirectMask | SubstructureNotifyMask, - &event - ); - XFlush(display); + status_set_datetime(buffer); sleep(1); } diff --git a/datetime.h b/datetime.h index 8605fa6..86e35e9 100644 --- a/datetime.h +++ b/datetime.h @@ -5,8 +5,5 @@ bool datetime_start(); void datetime_stop(); -void datetime_lock(); -void datetime_unlock(); -const char *datetime_get(); #endif // _DATETIME_H diff --git a/dwm.c b/dwm.c index b093b8d..dff8463 100644 --- a/dwm.c +++ b/dwm.c @@ -44,6 +44,7 @@ #include "atoms.h" #include "datetime.h" #include "drw.h" +#include "status.h" #include "util.h" /* macros */ @@ -253,6 +254,7 @@ static int updategeom(void); static void updatenumlockmask(void); static void updatesizehints(Client *c); static void updatestatus(void); +static void updatestatusexternal(void); static void updatesystray(void); static void updatesystrayicongeom(Client *i, int w, int h); static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); @@ -625,7 +627,7 @@ clientmessage(XEvent *e) return; } - if (cme->message_type == atoms->netatom[NetDateTime]) { + if (cme->message_type == atoms->netatom[NetStatusUpdate]) { updatestatus(); // TODO: maybe we need some filtering return; } @@ -1437,7 +1439,7 @@ propertynotify(XEvent *e) updatesystray(); } if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); + updatestatusexternal(); else if (ev->state == PropertyDelete) return; /* ignore */ else if ((c = wintoclient(ev->window))) { @@ -1822,7 +1824,7 @@ setup(void) updatesystray(); /* init bars */ updatebars(); - updatestatus(); + updatestatusexternal(); /* supporting window for NetWMCheck */ wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); XChangeProperty(dpy, wmcheckwin, atoms->netatom[NetWMCheck], XA_WINDOW, 32, @@ -2284,11 +2286,9 @@ updatesizehints(Client *c) void updatestatus(void) { - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) { - datetime_lock(); - sprintf(stext, "dwm-"VERSION" | %s", datetime_get()); - datetime_unlock(); - } + status_lock(); + sprintf(stext, "%s", status_get()); + status_unlock(); for (Monitor *m = mons; m; m = m->next) { drawbar(m); @@ -2297,6 +2297,18 @@ updatestatus(void) updatesystray(); } +void +updatestatusexternal(void) +{ + char buffer[256]; + + if (!gettextprop(root, XA_WM_NAME, buffer, sizeof(buffer))) { + sprintf(buffer, "dwm-"VERSION); + } + + status_set_external(buffer); +} + void updatesystrayicongeom(Client *i, int w, int h) { @@ -2632,6 +2644,10 @@ main(int argc, char *argv[]) if (!(dpy = XOpenDisplay(NULL))) die("dwm: cannot open display"); checkotherwm(); + if (!status_start()) { + status_stop(); + die("dwm: cannot start status service"); + } if (!datetime_start()) { datetime_stop(); die("dwm: cannot start datetime service"); @@ -2645,6 +2661,7 @@ main(int argc, char *argv[]) run(); cleanup(); datetime_stop(); + status_stop(); XCloseDisplay(dpy); return EXIT_SUCCESS; } diff --git a/status.c b/status.c new file mode 100644 index 0000000..4e70a07 --- /dev/null +++ b/status.c @@ -0,0 +1,120 @@ +#include "status.h" + +#include "atoms.h" + +#include +#include +#include +#include + +#define EXTERNAL_BUFFER_SIZE 256 +#define DATETIME_BUFFER_SIZE 32 + +#define BUFFER_SIZE (EXTERNAL_BUFFER_SIZE + 3 + DATETIME_BUFFER_SIZE) + +static void update(); + +static pthread_mutex_t mutex; +static bool running = false; + +static Display *display = None; +static Atoms atoms = NULL; + +static char buffer[BUFFER_SIZE]; +static char external_buffer[EXTERNAL_BUFFER_SIZE]; +static char datetime_buffer[DATETIME_BUFFER_SIZE]; + +void status_lock() +{ + pthread_mutex_lock(&mutex); +} + +void status_unlock() +{ + pthread_mutex_unlock(&mutex); +} + +const char *status_get() +{ + return buffer; +} + +bool status_start() +{ + status_lock(); + + if (running) return false; + + running = true; + + memset(buffer, 0, sizeof(buffer)); + memset(external_buffer, 0, sizeof(external_buffer)); + memset(datetime_buffer, 0, sizeof(datetime_buffer)); + + if ((display = XOpenDisplay(NULL)) == NULL) return false; + if ((atoms = atoms_create(display)) == NULL) return false; + + status_unlock(); + + return true; +} + +void status_stop() +{ + status_lock(); + + if (!running) return; + + running = false; + if (atoms != NULL) atoms_destroy(atoms); + if (display != None) XCloseDisplay(display); + + status_unlock(); +} + +void status_set_external(const char *const text) +{ + status_lock(); + + strncpy(external_buffer, text, EXTERNAL_BUFFER_SIZE); + external_buffer[EXTERNAL_BUFFER_SIZE - 1] = '\0'; + update(); + + status_unlock(); +} + +void status_set_datetime(const char *const text) +{ + status_lock(); + + strncpy(datetime_buffer, text, DATETIME_BUFFER_SIZE); + datetime_buffer[DATETIME_BUFFER_SIZE - 1] = '\0'; + update(); + + status_unlock(); +} + +static void update() +{ + sprintf(buffer, "%s | %s", external_buffer, datetime_buffer); + + XEvent event; + memset(&event, 0, sizeof(event)); + event.xclient.type = ClientMessage; + event.xclient.serial = 0; + event.xclient.send_event = True; + event.xclient.display = display; + event.xclient.window = DefaultRootWindow(display); + event.xclient.message_type = atoms->netatom[NetStatusUpdate]; + event.xclient.format = 32; + + XSendEvent( + display, + event.xclient.window, + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &event + ); + + XFlush(display); +} diff --git a/status.h b/status.h new file mode 100644 index 0000000..2bca139 --- /dev/null +++ b/status.h @@ -0,0 +1,15 @@ +#ifndef _STATUS_H +#define _STATUS_H + +#include + +bool status_start(); +void status_stop(); +void status_lock(); +void status_unlock(); +const char *status_get(); + +void status_set_external(const char *text); +void status_set_datetime(const char *text); + +#endif // _STATUS_H