Move status to separate module

This commit is contained in:
Alex Kotov 2021-11-12 16:11:59 +05:00
parent a1b44b3943
commit d6b0c95b91
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
8 changed files with 167 additions and 45 deletions

View file

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

View file

@ -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);

View file

@ -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 */

View file

@ -1,15 +1,17 @@
#include "datetime.h"
#include "atoms.h"
#include "status.h"
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <X11/Xlib.h>
#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);
}

View file

@ -5,8 +5,5 @@
bool datetime_start();
void datetime_stop();
void datetime_lock();
void datetime_unlock();
const char *datetime_get();
#endif // _DATETIME_H

33
dwm.c
View file

@ -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;
}

120
status.c Normal file
View file

@ -0,0 +1,120 @@
#include "status.h"
#include "atoms.h"
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#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);
}

15
status.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef _STATUS_H
#define _STATUS_H
#include <stdbool.h>
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