diff --git a/config.def.h b/config.def.h index a2ac963..92a6a81 100644 --- a/config.def.h +++ b/config.def.h @@ -60,6 +60,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; static const char *termcmd[] = { "st", NULL }; +#include "exitdwm.c" static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_p, spawn, {.v = dmenucmd } }, @@ -94,7 +95,7 @@ static Key keys[] = { TAGKEYS( XK_7, 6) TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, + { MODKEY|ShiftMask, XK_e, exitdwm, {0} }, }; /* button definitions */ diff --git a/exitdwm.c b/exitdwm.c new file mode 100644 index 0000000..74c514f --- /dev/null +++ b/exitdwm.c @@ -0,0 +1,87 @@ +# include +# include + +void exitdwm () +{ +# if \ + defined S_LOCK || \ + defined S_RESTART_DWM || \ + defined S_OFFSCREEN || \ + defined S_EXIT || \ + defined S_REBOOT || \ + defined S_SHUTDOWN || \ + defined S_LOCK_ICON || \ + defined S_RESTART_DWM_ICON || \ + defined S_OFFSCREEN_ICON || \ + defined S_EXIT_ICON || \ + defined S_REBOOT_ICON || \ + defined S_SHUTDOWN_ICON || \ + defined S_FORMAT || \ + defined S_FORMAT_CLEAR +# error (conflicting macro names) +# endif + +# define S_LOCK "Lock" +# define S_RESTART_DWM "restart Dwm" +# define S_OFFSCREEN "Off-screen" +# define S_EXIT "Exit" +# define S_REBOOT "Reboot" +# define S_SHUTDOWN "Shutdown" +# define S_LOCK_ICON "\uf023" // <= FontAwesome icons +# define S_RESTART_DWM_ICON "\uf01e" +# define S_OFFSCREEN_ICON "\uf108" +# define S_EXIT_ICON "\uf2f5" +# define S_REBOOT_ICON "\uf021" +# define S_SHUTDOWN_ICON "\uf011" + +# define S_FORMAT(ACTION) S_##ACTION##_ICON " " S_##ACTION +# define S_FORMAT_CLEAR "sed 's/^..//'" + + FILE * exit_menu = popen ( + "echo \"" + S_FORMAT (LOCK) "\n" + S_FORMAT (RESTART_DWM) "\n" + S_FORMAT (OFFSCREEN) "\n" + S_FORMAT (EXIT) "\n" + S_FORMAT (REBOOT) "\n" + S_FORMAT (SHUTDOWN) + "\" | dmenu -p exit: | " S_FORMAT_CLEAR + , + "r" + ); + + char exit_action [16]; + + if ( + exit_menu == NULL || + fscanf (exit_menu, "%15[a-zA-Z -]", exit_action) == EOF + ) { + fputs ("Error. Failure in exit_dwm.", stderr); + goto close_streams; + } + + if (strcmp (exit_action, S_LOCK) == 0) system ("slock & sleep .5; xset dpms force off"); + else if (strcmp (exit_action, S_RESTART_DWM) == 0) quit (& (const Arg) {1}); + else if (strcmp (exit_action, S_OFFSCREEN) == 0) system ("sleep .5; xset dpms force off"); + else if (strcmp (exit_action, S_EXIT) == 0) quit (& (const Arg) {0}); + else if (strcmp (exit_action, S_REBOOT) == 0) system ("systemctl reboot"); + else if (strcmp (exit_action, S_SHUTDOWN) == 0) system ("systemctl poweroff -i"); + +close_streams: + pclose (exit_menu); + +# undef S_LOCK +# undef S_RESTART_DWM +# undef S_OFFSCREEN +# undef S_EXIT +# undef S_REBOOT +# undef S_SHUTDOWN +# undef S_LOCK_ICON +# undef S_RESTART_DWM_ICON +# undef S_OFFSCREEN_ICON +# undef S_EXIT_ICON +# undef S_REBOOT_ICON +# undef S_SHUTDOWN_ICON +# undef S_FORMAT +# undef S_FORMAT_CLEAR +}