summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2015-09-16 22:37:59 +0200
committercos <cos>2016-07-28 20:52:44 +0200
commit26f0ba3074047d074e71c904baccfce0763e346d (patch)
tree512b2a1fe22871e8599aae5ac451b634d07fc360
parent492a06066ae5cca4054dbf3241863fb842eddcd1 (diff)
downloadratpoison-cr/add_confirmquit.zip
Prompt on interactive quit when confirmquit is true.cr/add_confirmquit
Quitting a window manager is a very special and dangerous operation compared to exiting an editor, a web browser or something else with a command syntax very similar to ratpoison's. This commit adds some protection for those (us) who occasionally unintentionally types quit at the wrong prompt.
-rw-r--r--doc/ratpoison.mdoc.17
-rw-r--r--doc/ratpoison.texi1
-rw-r--r--src/actions.c70
-rw-r--r--src/data.h3
-rw-r--r--src/main.c2
5 files changed, 81 insertions, 2 deletions
diff --git a/doc/ratpoison.mdoc.1 b/doc/ratpoison.mdoc.1
index 2e3c356..941f503 100644
--- a/doc/ratpoison.mdoc.1
+++ b/doc/ratpoison.mdoc.1
@@ -1141,6 +1141,13 @@ Decide if history expansion using ! is available.
Default is
.Li 0
(off).
+.It Cm confirmquit Li 0 | 1
+Protect against unintended window manager termination by prompting for
+confirmation when calling quit. (Only in interactive mode.)
+.Pp
+Default is
+.Li 0
+(off).
.El
.Sh FILES
.Bl -tag -width "%%sysconfdir%%/ratpoisonrc" -compact
diff --git a/doc/ratpoison.texi b/doc/ratpoison.texi
index da9da16..fb8e91d 100644
--- a/doc/ratpoison.texi
+++ b/doc/ratpoison.texi
@@ -1672,6 +1672,7 @@ Here is a list of variables that can be set:
@item historysize
@item historycompaction
@item historyexpansion
+@item confirmquit
@end itemize
@end deffn
diff --git a/src/actions.c b/src/actions.c
index c0fc569..4bfe639 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -83,6 +83,7 @@ static cmdret * set_historycompaction (struct cmdarg **args);
static cmdret * set_historyexpansion (struct cmdarg **args);
static cmdret * set_msgwait(struct cmdarg **args);
static cmdret * set_framemsgwait(struct cmdarg **args);
+static cmdret * set_confirmquit(struct cmdarg **args);
LIST_HEAD(set_vars);
@@ -154,6 +155,7 @@ init_set_vars(void)
add_set_var ("historyexpansion", set_historyexpansion, 1, "", arg_NUMBER);
add_set_var ("msgwait", set_msgwait, 1, "", arg_NUMBER);
add_set_var ("framemsgwait", set_framemsgwait, 1, "", arg_NUMBER);
+ add_set_var ("confirmquit", set_confirmquit, 1, "", arg_NUMBER);
}
/* rp_keymaps is ratpoison's list of keymaps. */
@@ -188,6 +190,41 @@ add_command (char *name, cmdret * (*fn)(int, struct cmdarg **), int nargs, int i
list_add (&cmd->node, &user_commands);
}
+static void
+modify_command (char *name, cmdret * (*fn)(int, struct cmdarg **), int nargs, int i_nrequired, int ni_nrequired, ...)
+{
+ int i = 0;
+ struct user_command *cmd;
+ va_list va;
+ struct user_command *cur;
+
+ cmd = xmalloc (sizeof (struct user_command));
+ cmd->name = name;
+ cmd->func = fn;
+ cmd->num_args = nargs;
+ cmd->ni_required_args = ni_nrequired;
+ cmd->i_required_args = i_nrequired;
+ cmd->args = nargs ? xmalloc (nargs * sizeof (struct argspec)) : NULL;
+
+ /* Remove existing command */
+ list_for_each_entry (cur, &user_commands, node)
+ {
+ if(&cur->func == &cmd->func)
+ list_del_init(&(cur->node));
+ }
+
+ /* Fill cmd->args */
+ va_start(va, ni_nrequired);
+ for (i=0; i<nargs; i++)
+ {
+ cmd->args[i].prompt = va_arg(va, char*);
+ cmd->args[i].type = va_arg(va, int);
+ }
+ va_end(va);
+
+ /* Add updated command */
+ list_add (&cmd->node, &user_commands);
+}
static void
user_command_free(struct user_command *cmd)
@@ -314,7 +351,8 @@ init_user_commands(void)
add_command ("other", cmd_other, 0, 0, 0);
add_command ("prev", cmd_prev, 0, 0, 0);
add_command ("prevscreen", cmd_prevscreen, 0, 0, 0);
- add_command ("quit", cmd_quit, 0, 0, 0);
+ add_command ("quit", cmd_quit, 1, 0, 0,
+ "Really quit? (yes/no): ", arg_STRING);
add_command ("ratinfo", cmd_ratinfo, 0, 0, 0);
add_command ("ratrelinfo", cmd_ratrelinfo, 0, 0, 0);
add_command ("banishrel", cmd_banishrel, 0, 0, 0);
@@ -2747,7 +2785,18 @@ cmd_newwm(int interactive UNUSED, struct cmdarg **args)
cmdret *
cmd_quit(int interactive UNUSED, struct cmdarg **args UNUSED)
{
- kill_signalled = 1;
+ const char *confirm = (args[0] ? ARG_STRING(0) : NULL);
+
+ if(defaults.confirm_on_quit) {
+ if(str_comp((char *) confirm, "yes", 3) && (strlen(confirm)==3)) {
+ kill_signalled = 1;
+ } else {
+ return cmdret_new (RET_FAILURE, "Aborting quit command.");
+ }
+ } else {
+ kill_signalled = 1;
+ }
+
return cmdret_new (RET_SUCCESS, NULL);
}
@@ -4237,6 +4286,23 @@ set_bwcolor (struct cmdarg **args)
return cmdret_new (RET_SUCCESS, NULL);
}
+static cmdret *
+set_confirmquit (struct cmdarg **args)
+{
+ if (args[0] == NULL)
+ return cmdret_new (RET_SUCCESS, "%d", defaults.confirm_on_quit);
+
+ if (ARG(0,number) < 0)
+ return cmdret_new (RET_FAILURE, "confirm_on_quit: %s", invalid_negative_arg);
+ else
+ defaults.confirm_on_quit = ARG(0,number);
+
+ modify_command ("quit", cmd_quit, 1, (defaults.confirm_on_quit ? 1 : 0), 0,
+ "Really quit? (yes/no): ", arg_STRING);
+
+ return cmdret_new (RET_SUCCESS, NULL);
+}
+
cmdret *
cmd_setenv (int interactive UNUSED, struct cmdarg **args)
{
diff --git a/src/data.h b/src/data.h
index f4bd185..4ccecbf 100644
--- a/src/data.h
+++ b/src/data.h
@@ -275,6 +275,9 @@ struct rp_defaults
/* Frame indicator format */
char *frame_fmt;
+
+ /* Prompt on quit */
+ int confirm_on_quit;
};
/* Information about a child process. */
diff --git a/src/main.c b/src/main.c
index 52dbcce..da6a0c0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -599,6 +599,8 @@ init_defaults (void)
defaults.history_expansion = False;
defaults.frame_selectors = xstrdup ("");
defaults.maxundos = 20;
+
+ defaults.confirm_on_quit = 0;
}
int