[wiki] [sites] [dwm][patch][sshawarespawn] add sshawarespawn patch || blatzfab

From: <git_AT_suckless.org>
Date: Fri, 16 Oct 2020 12:16:30 +0200

commit 69514edef1d2ddb495cf6a08e647a6ed04513e46
Author: blatzfab <fabian.blatz_AT_gmail.com>
Date: Fri Oct 16 10:13:24 2020 +0000

    [dwm][patch][sshawarespawn] add sshawarespawn patch

diff --git a/dwm.suckless.org/patches/sshawarespawn/dwm-sshawarespawn-20201015-61bb8b2.diff b/dwm.suckless.org/patches/sshawarespawn/dwm-sshawarespawn-20201015-61bb8b2.diff
new file mode 100644
index 00000000..6046566d
--- /dev/null
+++ b/dwm.suckless.org/patches/sshawarespawn/dwm-sshawarespawn-20201015-61bb8b2.diff
_AT_@ -0,0 +1,319 @@
+From b9b693eafe2925f323f54ff6444e09dbe8d9591a Mon Sep 17 00:00:00 2001
+From: blatzfab <fabian.blatz_AT_gmail.com>
+Date: Thu, 15 Oct 2020 21:28:36 +0000
+Subject: [PATCH] Adds ssh aware spawn command
+
+---
+ config.def.h | 2 +-
+ config.mk | 3 +-
+ dwm.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 176 insertions(+), 2 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..1a26f32 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -62,7 +62,7 @@ static const char *termcmd[] = { "st", NULL };
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
++ { MODKEY|ShiftMask, XK_Return, spawnsshaware, {.v = termcmd } },
+ { MODKEY, XK_b, togglebar, {0} },
+ { MODKEY, XK_j, focusstack, {.i = +1 } },
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+diff --git a/config.mk b/config.mk
+index 7084c33..bc99153 100644
+--- a/config.mk
++++ b/config.mk
+_AT_@ -19,10 +19,11 @@ FREETYPELIBS = -lfontconfig -lXft
+ FREETYPEINC = /usr/include/freetype2
+ # OpenBSD (uncomment)
+ #FREETYPEINC = ${X11INC}/freetype2
++#KVMLIB = -lkvm
+
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB} -lprocps
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index 664c527..0f623ea 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -28,6 +28,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <proc/readproc.h>
++#include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <X11/cursorfont.h>
+_AT_@ -40,6 +42,12 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
++#include <X11/Xlib-xcb.h>
++#include <xcb/res.h>
++#ifdef __OpenBSD__
++#include <sys/sysctl.h>
++#include <kvm.h>
++#endif /* __OpenBSD */
+
+ #include "drw.h"
+ #include "util.h"
+_AT_@ -93,6 +101,7 @@ struct Client {
+ int bw, oldbw;
+ unsigned int tags;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ pid_t pid;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+_AT_@ -156,6 +165,8 @@ static void clientmessage(XEvent *e);
+ static void configure(Client *c);
+ static void configurenotify(XEvent *e);
+ static void configurerequest(XEvent *e);
++static char* checksshsession(pid_t process);
++static int checkparents(pid_t pid, pid_t target);
+ static Monitor *createmon(void);
+ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+_AT_@ -172,6 +183,7 @@ static void focusstack(const Arg *arg);
+ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
++static int getprocinfo(pid_t pid, proc_t *procinfo);
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+_AT_@ -207,6 +219,8 @@ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static void spawnsshaware(const Arg *arg);
++static int strtopid(char *s, pid_t *pid);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+_AT_@ -230,6 +244,7 @@ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
++static pid_t winpid(Window w);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+_AT_@ -268,6 +283,7 @@ static Display *dpy;
+ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
++static xcb_connection_t *xcon;
+
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+_AT_@ -628,6 +644,62 @@ configurerequest(XEvent *e)
+ XSync(dpy, False);
+ }
+
++int
++checkparents(pid_t pid, pid_t target)
++{
++ proc_t *pinf = calloc(1, sizeof(proc_t));
++ pid_t current = pid;
++
++ while(current!=(pid_t)0 && current!=(pid_t)1 && current!=target){
++ getprocinfo(current, pinf);
++ current = pinf->ppid;
++ }
++ freeproc(pinf);
++ if(current==target)
++ return 1;
++ return 0;
++}
++
++char*
++checksshsession(pid_t process)
++{
++ struct dirent *dp;
++ DIR *dfd;
++ const char *dir = "/proc";
++ char filename_qfd[100] ;
++ pid_t pid;
++ proc_t* process_info = calloc(1, sizeof(proc_t));
++ struct stat stbuf;
++ char* res = 0;
++
++ if ((dfd = opendir(dir)) == NULL) {
++ fprintf(stderr, "Can't open %s
", dir);
++ freeproc(process_info);
++ return 0;
++ }
++
++ while ((dp = readdir(dfd)) != NULL && res == 0) {
++ sprintf( filename_qfd , "%s/%s",dir,dp->d_name);
++ if(stat(filename_qfd,&stbuf ) == -1) {
++ fprintf(stderr, "Unable to stat file: %s
",filename_qfd);
++ continue;
++ }
++ if (((stbuf.st_mode & S_IFMT) == S_IFDIR) && strtopid(dp->d_name, &pid)) {
++ getprocinfo(pid, process_info);
++ if(!process_info->cmdline)
++ continue;
++ char* cmdline = *process_info->cmdline;
++ if(strncmp("ssh ", cmdline, 4) == 0 && checkparents(pid, process)){
++ res = calloc(strlen(cmdline)+1, sizeof(char));
++ strcpy(res, cmdline);
++ }
++ }
++ }
++ freeproc(process_info);
++ free(dfd);
++ return res;
++}
++
+ Monitor *
+ createmon(void)
+ {
+_AT_@ -900,6 +972,19 @@ getstate(Window w)
+ return result;
+ }
+
++int
++getprocinfo(pid_t pid, proc_t *procinfo)
++{
++ int res = 1;
++ if(!procinfo)
++ return 0;
++ PROCTAB *pt_ptr = openproc(PROC_FILLARG | PROC_EDITCMDLCVT | PROC_FILLSTATUS | PROC_PID, &pid);
++ if(readproc(pt_ptr, procinfo))
++ res = 0;
++ closeproc(pt_ptr);
++ return res;
++}
++
+ int
+ gettextprop(Window w, Atom atom, char *text, unsigned int size)
+ {
+_AT_@ -1024,6 +1109,7 @@ manage(Window w, XWindowAttributes *wa)
+
+ c = ecalloc(1, sizeof(Client));
+ c->win = w;
++ c->pid = winpid(w);
+ /* geometry */
+ c->x = c->oldx = wa->x;
+ c->y = c->oldy = wa->y;
+_AT_@ -1637,6 +1723,38 @@ sigchld(int unused)
+ while (0 < waitpid(-1, NULL, WNOHANG));
+ }
+
++void
++spawnsshaware(const Arg *arg)
++{
++ if(selmon->sel) {
++ char* sshcmdline = checksshsession(selmon->sel->pid);
++ if(sshcmdline){
++ const char* sshcmd[] = {"st", "-e", "/bin/bash", "-c", sshcmdline, NULL};
++ Arg a = {.v=sshcmd};
++ spawn(&a);
++ free(sshcmdline);
++ }else{
++ spawn(arg);
++ }
++ }else{
++ spawn(arg);
++ }
++}
++
++int
++strtopid(char *s, pid_t *pid)
++{
++ long result = 0;
++ char *eptr;
++ if(!pid)
++ return 0;
++ result = strtol(s, &eptr, 10);
++ if((eptr && *eptr!='++ return 0;
++ *pid=(pid_t) result;
++ return 1;
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+_AT_@ -2077,6 +2195,59 @@ wintomon(Window w)
+ return selmon;
+ }
+
++pid_t
++winpid(Window w)
++{
++
++ pid_t result = 0;
++
++ #ifdef __linux__
++ xcb_res_client_id_spec_t spec = {0};
++ spec.client = w;
++ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
++
++ xcb_generic_error_t *e = NULL;
++ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
++ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
++
++ if (!r)
++ return (pid_t)0;
++
++ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
++ for (; i.rem; xcb_res_client_id_value_next(&i)) {
++ spec = i.data->spec;
++ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
++ uint32_t *t = xcb_res_client_id_value_value(i.data);
++ result = *t;
++ break;
++ }
++ }
++
++ free(r);
++
++ if (result == (pid_t)-1)
++ result = 0;
++
++ #endif /* __linux__ */
++
++ #ifdef __OpenBSD__
++ Atom type;
++ int format;
++ unsigned long len, bytes;
++ unsigned char *prop;
++ pid_t ret;
++
++ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 1), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
++ return 0;
++
++ ret = *(pid_t*)prop;
++ XFree(prop);
++ result = ret;
++
++ #endif /* __OpenBSD__ */
++ return result;
++}
++
+ /* There's no way to check accesses to destroyed windows, thus those cases are
+ * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
+ * default error handler, which may call exit. */
+_AT_@ -2138,6 +2309,8 @@ main(int argc, char *argv[])
+ fputs("warning: no locale support
", stderr);
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("dwm: cannot open display");
++ if (!(xcon = XGetXCBConnection(dpy)))
++ die("dwm: cannot get xcb connection
");
+ checkotherwm();
+ setup();
+ #ifdef __OpenBSD__
+--
+2.28.0
+
diff --git a/dwm.suckless.org/patches/sshawarespawn/dwm-sshawarespawn-6.2.diff b/dwm.suckless.org/patches/sshawarespawn/dwm-sshawarespawn-6.2.diff
new file mode 100644
index 00000000..912879df
--- /dev/null
+++ b/dwm.suckless.org/patches/sshawarespawn/dwm-sshawarespawn-6.2.diff
_AT_@ -0,0 +1,320 @@
+From fc232a3075835e01c1dab6b199ec8817d911d0be Mon Sep 17 00:00:00 2001
+From: blatzfab <fabian.blatz_AT_gmail.com>
+Date: Fri, 16 Oct 2020 09:44:24 +0000
+Subject: [PATCH] Adds ssh aware spawn command
+
+---
+ config.def.h | 2 +-
+ config.mk | 3 +-
+ dwm.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 177 insertions(+), 2 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1c0b587..1121d4d 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -62,7 +62,7 @@ static const char *termcmd[] = { "st", NULL };
+ static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenucmd } },
+- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
++ { MODKEY|ShiftMask, XK_Return, spawnsshaware, {.v = termcmd } },
+ { MODKEY, XK_b, togglebar, {0} },
+ { MODKEY, XK_j, focusstack, {.i = +1 } },
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+diff --git a/config.mk b/config.mk
+index 6d36cb7..5272bdc 100644
+--- a/config.mk
++++ b/config.mk
+_AT_@ -19,10 +19,11 @@ FREETYPELIBS = -lfontconfig -lXft
+ FREETYPEINC = /usr/include/freetype2
+ # OpenBSD (uncomment)
+ #FREETYPEINC = ${X11INC}/freetype2
++#KVMLIB = -lkvm
+
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB} -lprocps
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index 4465af1..bd35817 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -28,6 +28,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <proc/readproc.h>
++#include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <X11/cursorfont.h>
+_AT_@ -40,6 +42,12 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
++#include <X11/Xlib-xcb.h>
++#include <xcb/res.h>
++#ifdef __OpenBSD__
++#include <sys/sysctl.h>
++#include <kvm.h>
++#endif /* __OpenBSD */
+
+ #include "drw.h"
+ #include "util.h"
+_AT_@ -93,6 +101,7 @@ struct Client {
+ int bw, oldbw;
+ unsigned int tags;
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ pid_t pid;
+ Client *next;
+ Client *snext;
+ Monitor *mon;
+_AT_@ -156,6 +165,8 @@ static void clientmessage(XEvent *e);
+ static void configure(Client *c);
+ static void configurenotify(XEvent *e);
+ static void configurerequest(XEvent *e);
++static char* checksshsession(pid_t process);
++static int checkparents(pid_t pid, pid_t target);
+ static Monitor *createmon(void);
+ static void destroynotify(XEvent *e);
+ static void detach(Client *c);
+_AT_@ -171,6 +182,7 @@ static void focusmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
++static int getprocinfo(pid_t pid, proc_t *procinfo);
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+_AT_@ -206,6 +218,8 @@ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static void spawnsshaware(const Arg *arg);
++static int strtopid(char *s, pid_t *pid);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+_AT_@ -229,6 +243,7 @@ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
++static pid_t winpid(Window w);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+_AT_@ -267,6 +282,7 @@ static Display *dpy;
+ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
++static xcb_connection_t *xcon;
+
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+_AT_@ -575,6 +591,63 @@ configurenotify(XEvent *e)
+ }
+ }
+
++int
++checkparents(pid_t pid, pid_t target)
++{
++ proc_t *pinf = calloc(1, sizeof(proc_t));
++ pid_t current = pid;
++
++ while(current!=(pid_t)0 && current!=(pid_t)1 && current!=target){
++ getprocinfo(current, pinf);
++ current = pinf->ppid;
++ }
++ freeproc(pinf);
++ if(current==target)
++ return 1;
++ return 0;
++}
++
++char*
++checksshsession(pid_t process)
++{
++ struct dirent *dp;
++ DIR *dfd;
++ const char *dir = "/proc";
++ char filename_qfd[100] ;
++ pid_t pid;
++ proc_t* process_info = calloc(1, sizeof(proc_t));
++ struct stat stbuf;
++ char* res = 0;
++
++ if ((dfd = opendir(dir)) == NULL) {
++ fprintf(stderr, "Can't open %s
", dir);
++ freeproc(process_info);
++ return 0;
++ }
++
++ while ((dp = readdir(dfd)) != NULL && res == 0) {
++ sprintf( filename_qfd , "%s/%s",dir,dp->d_name);
++ if(stat(filename_qfd,&stbuf ) == -1) {
++ fprintf(stderr, "Unable to stat file: %s
",filename_qfd);
++ continue;
++ }
++ if (((stbuf.st_mode & S_IFMT) == S_IFDIR) && strtopid(dp->d_name, &pid)) {
++ getprocinfo(pid, process_info);
++ if(!process_info->cmdline)
++ continue;
++ char* cmdline = *process_info->cmdline;
++ if(strncmp("ssh ", cmdline, 4) == 0 && checkparents(pid, process)){
++ res = calloc(strlen(cmdline)+1, sizeof(char));
++ strcpy(res, cmdline);
++ }
++ }
++ }
++ freeproc(process_info);
++ free(dfd);
++ return res;
++}
++
++
+ void
+ configurerequest(XEvent *e)
+ {
+_AT_@ -899,6 +972,19 @@ getstate(Window w)
+ return result;
+ }
+
++int
++getprocinfo(pid_t pid, proc_t *procinfo)
++{
++ int res = 1;
++ if(!procinfo)
++ return 0;
++ PROCTAB *pt_ptr = openproc(PROC_FILLARG | PROC_EDITCMDLCVT | PROC_FILLSTATUS | PROC_PID, &pid);
++ if(readproc(pt_ptr, procinfo))
++ res = 0;
++ closeproc(pt_ptr);
++ return res;
++}
++
+ int
+ gettextprop(Window w, Atom atom, char *text, unsigned int size)
+ {
+_AT_@ -1023,6 +1109,7 @@ manage(Window w, XWindowAttributes *wa)
+
+ c = ecalloc(1, sizeof(Client));
+ c->win = w;
++ c->pid = winpid(w);
+ /* geometry */
+ c->x = c->oldx = wa->x;
+ c->y = c->oldy = wa->y;
+_AT_@ -1636,6 +1723,38 @@ sigchld(int unused)
+ while (0 < waitpid(-1, NULL, WNOHANG));
+ }
+
++void
++spawnsshaware(const Arg *arg)
++{
++ if(selmon->sel) {
++ char* sshcmdline = checksshsession(selmon->sel->pid);
++ if(sshcmdline){
++ const char* sshcmd[] = {"st", "-e", "/bin/bash", "-c", sshcmdline, NULL};
++ Arg a = {.v=sshcmd};
++ spawn(&a);
++ free(sshcmdline);
++ }else{
++ spawn(arg);
++ }
++ }else{
++ spawn(arg);
++ }
++}
++
++int
++strtopid(char *s, pid_t *pid)
++{
++ long result = 0;
++ char *eptr;
++ if(!pid)
++ return 0;
++ result = strtol(s, &eptr, 10);
++ if((eptr && *eptr!='++ return 0;
++ *pid=(pid_t) result;
++ return 1;
++}
++
+ void
+ spawn(const Arg *arg)
+ {
+_AT_@ -2074,6 +2193,59 @@ wintomon(Window w)
+ return selmon;
+ }
+
++
++pid_t
++winpid(Window w)
++{
++ pid_t result = 0;
++
++ #ifdef __linux__
++ xcb_res_client_id_spec_t spec = {0};
++ spec.client = w;
++ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
++
++ xcb_generic_error_t *e = NULL;
++ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
++ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
++
++ if (!r)
++ return (pid_t)0;
++
++ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
++ for (; i.rem; xcb_res_client_id_value_next(&i)) {
++ spec = i.data->spec;
++ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
++ uint32_t *t = xcb_res_client_id_value_value(i.data);
++ result = *t;
++ break;
++ }
++ }
++
++ free(r);
++
++ if (result == (pid_t)-1)
++ result = 0;
++
++ #endif /* __linux__ */
++
++ #ifdef __OpenBSD__
++ Atom type;
++ int format;
++ unsigned long len, bytes;
++ unsigned char *prop;
++ pid_t ret;
++
++ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 1), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
++ return 0;
++
++ ret = *(pid_t*)prop;
++ XFree(prop);
++ result = ret;
++
++ #endif /* __OpenBSD__ */
++ return result;
++}
++
+ /* There's no way to check accesses to destroyed windows, thus those cases are
+ * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
+ * default error handler, which may call exit. */
+_AT_@ -2135,6 +2307,8 @@ main(int argc, char *argv[])
+ fputs("warning: no locale support
", stderr);
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("dwm: cannot open display");
++ if (!(xcon = XGetXCBConnection(dpy)))
++ die("dwm: cannot get xcb connection
");
+ checkotherwm();
+ setup();
+ #ifdef __OpenBSD__
+--
+2.28.0
+
diff --git a/dwm.suckless.org/patches/sshawarespawn/index.md b/dwm.suckless.org/patches/sshawarespawn/index.md
new file mode 100644
index 00000000..fcd077de
--- /dev/null
+++ b/dwm.suckless.org/patches/sshawarespawn/index.md
_AT_@ -0,0 +1,45 @@
+sshawarespawn
+=============
+
+Description
+-----------
+This patch adds the ability to spawn a new terminal with ssh awareness, meaning
+that if your current selected client has an open ssh sesion, a newly created
+client will copy the ssh command and execute it. The spawning also carries over
+additional flags you have given to ssh. If your current client does not have an
+ssh session it executes the provided command.
+
+It works by crawling all of the processes for ssh sessions and traversing the
+process tree upwards to check if your current client is a parent of an ssh
+session.
+
+This patch borrows the `winpid` function from the swallow patch. My thanks to:
+* Rob King
+* Laslo Hunhold
+* Petr Ĺ abata
+* wtl
+* John Wilkes
+* Ben Raskin
+
+Depedencies
+-----------
+
+* libxcb
+* Xlib-libxcb
+* xcb-res
+* libprocps
+
+Download
+--------
+* [dwm-sshawarespawn-20201015-61bb8b2.diff](dwm-sshawarespawn-20201015-61bb8b2.diff)
+* [dwm-sshawarespawn-6.2.diff](dwm-sshawarespawn-6.2.diff)
+
+Notes
+-----
+Since the patch relies on walking the process tree, which is OS-specific,
+compatibility with other operating systems is not guaranteed. If you want to
+help expand the list of supported plattforms please contact me.
+
+Authors
+-------
+* Fabian Blatz - fabian.blatz at gmail period com
Received on Fri Oct 16 2020 - 12:16:30 CEST

This archive was generated by hypermail 2.3.0 : Fri Oct 16 2020 - 12:24:46 CEST