From b822d5405ab903ceee2d183aee0ef265d3105374 Mon Sep 17 00:00:00 2001 From: mrsu Date: Wed, 12 Jun 2024 11:26:40 +0100 Subject: [PATCH] patch restoreafterrestart --- config.def.h | 3 + dwm.1 | 10 ++ dwm.c | 75 ++++++++++ patches/dwm-restartsig-20180523-6.2.diff | 139 ++++++++++++++++++ ...-restoreafterrestart-20220709-d3f93c7.diff | 101 +++++++++++++ 5 files changed, 328 insertions(+) create mode 100644 patches/dwm-restartsig-20180523-6.2.diff create mode 100644 patches/dwm-restoreafterrestart-20220709-d3f93c7.diff diff --git a/config.def.h b/config.def.h index f0e0ac7..0cefc45 100644 --- a/config.def.h +++ b/config.def.h @@ -1,5 +1,7 @@ /* See LICENSE file for copyright and license details. */ +#define SESSION_FILE "/tmp/dwm-session" + /* appearance */ static unsigned int borderpx = 6; /* border pixel of windows */ static const unsigned int gappx = 10; /* gaps between windows */ @@ -98,6 +100,7 @@ static const Key keys[] = { TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) { MODKEY|ShiftMask, XK_q, quit, {0} }, + { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, }; /* button definitions */ diff --git a/dwm.1 b/dwm.1 index ddc8321..7b6cadb 100644 --- a/dwm.1 +++ b/dwm.1 @@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view. .TP .B Mod1\-Shift\-q Quit dwm. +.TP +.B Mod1\-Control\-Shift\-q +Restart dwm. .SS Mouse commands .TP .B Mod1\-Button1 @@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float .SH CUSTOMIZATION dwm is customized by creating a custom config.h and (re)compiling the source code. This keeps it fast, secure and simple. +.SH SIGNALS +.TP +.B SIGHUP - 1 +Restart the dwm process. +.TP +.B SIGTERM - 15 +Cleanly terminate the dwm process. .SH SEE ALSO .BR dmenu (1), .BR st (1) diff --git a/dwm.c b/dwm.c index 14ea103..c7b23ab 100644 --- a/dwm.c +++ b/dwm.c @@ -207,6 +207,8 @@ static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); static void showhide(Client *c); +static void sighup(int unused); +static void sigterm(int unused); static void spawn(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); @@ -262,6 +264,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { [UnmapNotify] = unmapnotify }; static Atom wmatom[WMLast], netatom[NetLast]; +static int restart = 0; static int running = 1; static Cur *cursor[CurLast]; static Clr **scheme; @@ -1258,10 +1261,63 @@ propertynotify(XEvent *e) } } +void +saveSession(void) +{ + FILE *fw = fopen(SESSION_FILE, "w"); + for (Client *c = selmon->clients; c != NULL; c = c->next) { // get all the clients with their tags and write them to the file + fprintf(fw, "%lu %u\n", c->win, c->tags); + } + fclose(fw); +} + +void +restoreSession(void) +{ + // restore session + FILE *fr = fopen(SESSION_FILE, "r"); + if (!fr) + return; + + char *str = malloc(23 * sizeof(char)); // allocate enough space for excepted input from text file + while (fscanf(fr, "%[^\n] ", str) != EOF) { // read file till the end + long unsigned int winId; + unsigned int tagsForWin; + int check = sscanf(str, "%lu %u", &winId, &tagsForWin); // get data + if (check != 2) // break loop if data wasn't read correctly + break; + + for (Client *c = selmon->clients; c ; c = c->next) { // add tags to every window by winId + if (c->win == winId) { + c->tags = tagsForWin; + break; + } + } + } + + for (Client *c = selmon->clients; c ; c = c->next) { // refocus on windows + focus(c); + restack(c->mon); + } + + for (Monitor *m = selmon; m; m = m->next) // rearrange all monitors + arrange(m); + + free(str); + fclose(fr); + + // delete a file + remove(SESSION_FILE); +} + void quit(const Arg *arg) { + if(arg->i) restart = 1; running = 0; + + if (restart == 1) + saveSession(); } Monitor * @@ -1566,6 +1622,9 @@ setup(void) /* clean up any zombies (inherited from .xinitrc etc) immediately */ while (waitpid(-1, NULL, WNOHANG) > 0); + signal(SIGHUP, sighup); + signal(SIGTERM, sigterm); + /* init screen */ screen = DefaultScreen(dpy); sw = DisplayWidth(dpy, screen); @@ -1657,6 +1716,20 @@ showhide(Client *c) } } +void +sighup(int unused) +{ + Arg a = {.i = 1}; + quit(&a); +} + +void +sigterm(int unused) +{ + Arg a = {.i = 0}; + quit(&a); +} + void spawn(const Arg *arg) { @@ -2171,7 +2244,9 @@ main(int argc, char *argv[]) die("pledge"); #endif /* __OpenBSD__ */ scan(); + restoreSession(); run(); + if(restart) execvp(argv[0], argv); cleanup(); XCloseDisplay(dpy); return EXIT_SUCCESS; diff --git a/patches/dwm-restartsig-20180523-6.2.diff b/patches/dwm-restartsig-20180523-6.2.diff new file mode 100644 index 0000000..f1f8680 --- /dev/null +++ b/patches/dwm-restartsig-20180523-6.2.diff @@ -0,0 +1,139 @@ +From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001 +From: Christopher Drelich +Date: Wed, 23 May 2018 22:50:38 -0400 +Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM + handlers. + +Modified quit() to restart if it receives arg .i = 1 +MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that. + +Signal handlers were handled for SIGHUP and SIGTERM. +If dwm receives these signals it calls quit() with +arg .i = to 1 or 0, respectively. + +To restart dwm: +MOD+CTRL+SHIFT+Q +or +kill -HUP dwmpid + +To quit dwm cleanly: +MOD+SHIFT+Q +or +kill -TERM dwmpid +--- + config.def.h | 1 + + dwm.1 | 10 ++++++++++ + dwm.c | 22 ++++++++++++++++++++++ + 3 files changed, 33 insertions(+) + +diff --git a/config.def.h b/config.def.h +index a9ac303..e559429 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -94,6 +94,7 @@ static Key keys[] = { + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, ++ { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, + }; + + /* button definitions */ +diff --git a/dwm.1 b/dwm.1 +index 13b3729..36a331c 100644 +--- a/dwm.1 ++++ b/dwm.1 +@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view. + .TP + .B Mod1\-Shift\-q + Quit dwm. ++.TP ++.B Mod1\-Control\-Shift\-q ++Restart dwm. + .SS Mouse commands + .TP + .B Mod1\-Button1 +@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float + .SH CUSTOMIZATION + dwm is customized by creating a custom config.h and (re)compiling the source + code. This keeps it fast, secure and simple. ++.SH SIGNALS ++.TP ++.B SIGHUP - 1 ++Restart the dwm process. ++.TP ++.B SIGTERM - 15 ++Cleanly terminate the dwm process. + .SH SEE ALSO + .BR dmenu (1), + .BR st (1) +diff --git a/dwm.c b/dwm.c +index bb95e26..286eecd 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -205,6 +205,8 @@ static void setup(void); + static void seturgent(Client *c, int urg); + static void showhide(Client *c); + static void sigchld(int unused); ++static void sighup(int unused); ++static void sigterm(int unused); + static void spawn(const Arg *arg); + static void tag(const Arg *arg); + static void tagmon(const Arg *arg); +@@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { + [UnmapNotify] = unmapnotify + }; + static Atom wmatom[WMLast], netatom[NetLast]; ++static int restart = 0; + static int running = 1; + static Cur *cursor[CurLast]; + static Clr **scheme; +@@ -1248,6 +1251,7 @@ propertynotify(XEvent *e) + void + quit(const Arg *arg) + { ++ if(arg->i) restart = 1; + running = 0; + } + +@@ -1536,6 +1540,9 @@ setup(void) + /* clean up any zombies immediately */ + sigchld(0); + ++ signal(SIGHUP, sighup); ++ signal(SIGTERM, sigterm); ++ + /* init screen */ + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); +@@ -1637,6 +1644,20 @@ sigchld(int unused) + } + + void ++sighup(int unused) ++{ ++ Arg a = {.i = 1}; ++ quit(&a); ++} ++ ++void ++sigterm(int unused) ++{ ++ Arg a = {.i = 0}; ++ quit(&a); ++} ++ ++void + spawn(const Arg *arg) + { + if (arg->v == dmenucmd) +@@ -2139,6 +2160,7 @@ main(int argc, char *argv[]) + setup(); + scan(); + run(); ++ if(restart) execvp(argv[0], argv); + cleanup(); + XCloseDisplay(dpy); + return EXIT_SUCCESS; +-- +2.7.4 + diff --git a/patches/dwm-restoreafterrestart-20220709-d3f93c7.diff b/patches/dwm-restoreafterrestart-20220709-d3f93c7.diff new file mode 100644 index 0000000..cfcb607 --- /dev/null +++ b/patches/dwm-restoreafterrestart-20220709-d3f93c7.diff @@ -0,0 +1,101 @@ +From 9fd4a02b57aa8a764d8105d5f2f854372f4ef559 Mon Sep 17 00:00:00 2001 +From: ViliamKovac1223 +Date: Sat, 9 Jul 2022 17:35:54 +0200 +Subject: [PATCH] add restore patch + +--- + config.def.h | 2 ++ + dwm.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 55 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 6ec4146..0b91976 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -1,5 +1,7 @@ + /* See LICENSE file for copyright and license details. */ + ++#define SESSION_FILE "/tmp/dwm-session" ++ + /* appearance */ + static const unsigned int borderpx = 1; /* border pixel of windows */ + static const unsigned int snap = 32; /* snap pixel */ +diff --git a/dwm.c b/dwm.c +index 74cec7e..76b40a2 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -1255,11 +1255,63 @@ propertynotify(XEvent *e) + } + } + ++void ++saveSession(void) ++{ ++ FILE *fw = fopen(SESSION_FILE, "w"); ++ for (Client *c = selmon->clients; c != NULL; c = c->next) { // get all the clients with their tags and write them to the file ++ fprintf(fw, "%lu %u\n", c->win, c->tags); ++ } ++ fclose(fw); ++} ++ ++void ++restoreSession(void) ++{ ++ // restore session ++ FILE *fr = fopen(SESSION_FILE, "r"); ++ if (!fr) ++ return; ++ ++ char *str = malloc(23 * sizeof(char)); // allocate enough space for excepted input from text file ++ while (fscanf(fr, "%[^\n] ", str) != EOF) { // read file till the end ++ long unsigned int winId; ++ unsigned int tagsForWin; ++ int check = sscanf(str, "%lu %u", &winId, &tagsForWin); // get data ++ if (check != 2) // break loop if data wasn't read correctly ++ break; ++ ++ for (Client *c = selmon->clients; c ; c = c->next) { // add tags to every window by winId ++ if (c->win == winId) { ++ c->tags = tagsForWin; ++ break; ++ } ++ } ++ } ++ ++ for (Client *c = selmon->clients; c ; c = c->next) { // refocus on windows ++ focus(c); ++ restack(c->mon); ++ } ++ ++ for (Monitor *m = selmon; m; m = m->next) // rearrange all monitors ++ arrange(m); ++ ++ free(str); ++ fclose(fr); ++ ++ // delete a file ++ remove(SESSION_FILE); ++} ++ + void + quit(const Arg *arg) + { + if(arg->i) restart = 1; + running = 0; ++ ++ if (restart == 1) ++ saveSession(); + } + + Monitor * +@@ -2173,6 +2225,7 @@ main(int argc, char *argv[]) + die("pledge"); + #endif /* __OpenBSD__ */ + scan(); ++ restoreSession(); + run(); + if(restart) execvp(argv[0], argv); + cleanup(); +-- +2.35.1 +