Adding IPC v1.5.5 patch

pull/48/head
bakkeby 4 years ago
parent 260bd11a53
commit 4379517c25

1
.gitignore vendored

@ -1,4 +1,5 @@
*.o
dwm
dwm-msg
config.h
patches.h

@ -6,7 +6,11 @@ include config.mk
SRC = drw.c dwm.c util.c
OBJ = ${SRC:.c=.o}
ifdef YAJLLIBS
all: options dwm dwm-msg
else
all: options dwm
endif
options:
@echo dwm build options:
@ -28,8 +32,14 @@ patches.h:
dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
ifdef YAJLLIBS
dwm-msg:
${CC} -o $@ patch/ipc/dwm-msg.c ${LDFLAGS}
endif
clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
rm -f dwm-msg
dist: clean
mkdir -p dwm-${VERSION}
@ -42,8 +52,14 @@ dist: clean
install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f dwm ${DESTDIR}${PREFIX}/bin
ifdef YAJLLIBS
cp -f dwm-msg ${DESTDIR}${PREFIX}/bin
endif
#cp -f patch/dwmc ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
ifdef YAJLLIBS
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg
endif
mkdir -p ${DESTDIR}${MANPREFIX}/man1
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1

@ -15,7 +15,7 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t
### Changelog:
2020-09-07 - Scratchpads improvement (multi-monitor support)
2020-09-07 - Scratchpads improvement (multi-monitor support). Added ipc v1.5.5 patch.
2020-09-05 - Assortment of fullscreen improvements
@ -350,6 +350,10 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t
- lets custom insets from each edge of the screen to be defined
- an example use case would be to make space for an external bar
- [ipc](https://github.com/mihirlad55/dwm-ipc)
- implements inter-process communication through a UNIX socket for dwm
- allows for the window manager to be queried for information, e.g. listen for events such as tag or layout changes, as well as send commands to control the window manager via other programs
- [ispermanent](https://dwm.suckless.org/patches/ispermanent/)
- adds rule option for clients to avoid accidental termination by killclient for sticky windows

@ -1308,3 +1308,23 @@ static Button buttons[] = {
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
#if IPC_PATCH
static const char *ipcsockpath = "/tmp/dwm.sock";
static IPCCommand ipccommands[] = {
IPCCOMMAND( view, 1, {ARG_TYPE_UINT} ),
IPCCOMMAND( toggleview, 1, {ARG_TYPE_UINT} ),
IPCCOMMAND( tag, 1, {ARG_TYPE_UINT} ),
IPCCOMMAND( toggletag, 1, {ARG_TYPE_UINT} ),
IPCCOMMAND( tagmon, 1, {ARG_TYPE_UINT} ),
IPCCOMMAND( focusmon, 1, {ARG_TYPE_SINT} ),
IPCCOMMAND( focusstack, 1, {ARG_TYPE_SINT} ),
IPCCOMMAND( zoom, 1, {ARG_TYPE_NONE} ),
IPCCOMMAND( incnmaster, 1, {ARG_TYPE_SINT} ),
IPCCOMMAND( killclient, 1, {ARG_TYPE_SINT} ),
IPCCOMMAND( togglefloating, 1, {ARG_TYPE_NONE} ),
IPCCOMMAND( setmfact, 1, {ARG_TYPE_FLOAT} ),
IPCCOMMAND( setlayoutsafe, 1, {ARG_TYPE_PTR} ),
IPCCOMMAND( quit, 1, {ARG_TYPE_NONE} )
};
#endif // IPC_PATCH

@ -30,6 +30,10 @@ FREETYPEINC = /usr/include/freetype2
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
# Uncomment for the ipc patch / IPC_PATCH
#YAJLLIBS = -I-lyajl
#YAJLINC = /usr/include/yajl
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
#XEXTLIB = -lXext
@ -37,8 +41,8 @@ FREETYPEINC = /usr/include/freetype2
#XCBLIBS = -lX11-xcb -lxcb -lxcb-res
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} ${PANGOINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${PANGOLIB}
INCS = -I${X11INC} -I${FREETYPEINC} ${PANGOINC} ${YAJLLIBS}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${PANGOLIB} ${YAJLLIBS}
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}

91
dwm.c

@ -219,9 +219,28 @@ enum {
BAR_ALIGN_LAST
}; /* bar alignment */
#if IPC_PATCH
typedef struct TagState TagState;
struct TagState {
int selected;
int occupied;
int urgent;
};
typedef struct ClientState ClientState;
struct ClientState {
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
};
#endif // IPC_PATCH
typedef union {
#if IPC_PATCH
long i;
unsigned long ui;
#else
int i;
unsigned int ui;
#endif // IPC_PATCH
float f;
const void *v;
} Arg;
@ -333,6 +352,9 @@ struct Client {
#endif // SWALLOW_PATCH
Monitor *mon;
Window win;
#if IPC_PATCH
ClientState prevstate;
#endif // IPC_PATCH
};
typedef struct {
@ -414,6 +436,12 @@ struct Monitor {
#if INSETS_PATCH
Inset inset;
#endif // INSETS_PATCH
#if IPC_PATCH
char lastltsymbol[16];
TagState tagstate;
Client *lastsel;
const Layout *lastlt;
#endif // IPC_PATCH
};
typedef struct {
@ -1039,6 +1067,13 @@ cleanup(void)
XSync(dpy, False);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
#if IPC_PATCH
ipc_cleanup();
if (close(epoll_fd) < 0)
fprintf(stderr, "Failed to close epoll file descriptor\n");
#endif // IPC_PATCH
}
void
@ -2638,6 +2673,46 @@ restack(Monitor *m)
#endif // WARP_PATCH
}
#if IPC_PATCH
void
run(void)
{
int event_count = 0;
const int MAX_EVENTS = 10;
struct epoll_event events[MAX_EVENTS];
XSync(dpy, False);
/* main event loop */
while (running) {
event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
for (int i = 0; i < event_count; i++) {
int event_fd = events[i].data.fd;
DEBUG("Got event from fd %d\n", event_fd);
if (event_fd == dpy_fd) {
// -1 means EPOLLHUP
if (handlexevent(events + i) == -1)
return;
} else if (event_fd == ipc_get_sock_fd()) {
ipc_handle_socket_epoll_event(events + i);
} else if (ipc_is_client_registered(event_fd)) {
if (ipc_handle_client_epoll_event(events + i, mons, &lastselmon, selmon,
NUMTAGS, layouts, LENGTH(layouts)) < 0) {
fprintf(stderr, "Error handling IPC event on fd %d\n", event_fd);
}
} else {
fprintf(stderr, "Got event from unknown fd %d, ptr %p, u32 %d, u64 %lu",
event_fd, events[i].data.ptr, events[i].data.u32,
events[i].data.u64);
fprintf(stderr, " with events %d\n", events[i].events);
return;
}
}
}
}
#else
void
run(void)
{
@ -2648,6 +2723,7 @@ run(void)
if (handler[ev.type])
handler[ev.type](&ev); /* call handler */
}
#endif // IPC_PATCH
void
scan(void)
@ -3096,6 +3172,9 @@ setup(void)
XSelectInput(dpy, root, wa.event_mask);
grabkeys();
focus(NULL);
#if IPC_PATCH
setupepoll();
#endif // IPC_PATCH
}
@ -3910,10 +3989,22 @@ updatestatus(void)
void
updatetitle(Client *c)
{
#if IPC_PATCH
char oldname[sizeof(c->name)];
strcpy(oldname, c->name);
#endif // IPC_PATCH
if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
if (c->name[0] == '\0') /* hack to mark broken clients */
strcpy(c->name, broken);
#if IPC_PATCH
for (Monitor *m = mons; m; m = m->next) {
if (m->sel == c && strcmp(oldname, c->name) != 0)
ipc_focused_title_change_event(m->num, c->win, oldname, c->name);
}
#endif // IPC_PATCH
}
void

@ -62,9 +62,17 @@ fake_signal(void)
if (paramn == 1) arg = (Arg) {0};
else if (paramn > 2) return 1;
else if (strncmp(param, "i", n - len_str_sig) == 0)
#if IPC_PATCH
sscanf(fsignal + len_indicator + n, "%li", &(arg.i));
#else
sscanf(fsignal + len_indicator + n, "%i", &(arg.i));
#endif // IPC_PATCH
else if (strncmp(param, "ui", n - len_str_sig) == 0)
#if IPC_PATCH
sscanf(fsignal + len_indicator + n, "%lu", &(arg.ui));
#else
sscanf(fsignal + len_indicator + n, "%u", &(arg.ui));
#endif // IPC_PATCH
else if (strncmp(param, "f", n - len_str_sig) == 0)
sscanf(fsignal + len_indicator + n, "%f", &(arg.f));
else return 1;

@ -138,6 +138,15 @@
#if INPLACEROTATE_PATCH
#include "inplacerotate.c"
#endif
#if IPC_PATCH
#include "ipc.c"
#ifdef VERSION
#include "ipc/IPCClient.c"
#include "ipc/yajl_dumps.c"
#include "ipc/ipc.c"
#include "ipc/util.c"
#endif
#endif // IPC_PATCH
#if INSETS_PATCH
#include "insets.c"
#endif

@ -138,6 +138,11 @@
#if INPLACEROTATE_PATCH
#include "inplacerotate.h"
#endif
#if IPC_PATCH
#include "ipc.h"
#include "ipc/ipc.h"
#include "ipc/util.h"
#endif
#if INSETS_PATCH
#include "insets.h"
#endif

@ -532,6 +532,20 @@
*/
#define INSETS_PATCH 0
/* This patch (v1.5.5) implements inter-process communication through a UNIX socket for dwm. This
* allows for the window manager to be queried for information, e.g. listen for events such as tag
* or layout changes, as well as send commands to control the window manager via other programs.
*
* You need to uncomment the corresponding lines in config.mk to use the -lyajl library
* when including this patch.
* This patch depends on the following additional library:
* - yajl
*
* https://github.com/mihirlad55/dwm-ipc
* https://dwm.suckless.org/patches/ipc/
*/
#define IPC_PATCH 0
/* Adds rule option for clients to avoid accidental termination by killclient for sticky windows.
* https://dwm.suckless.org/patches/ispermanent/
*/

@ -8,5 +8,11 @@
#endif
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#ifdef _DEBUG
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#else
#define DEBUG(...)
#endif
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);

Loading…
Cancel
Save