ref: 4752c7a2d9bd83d41d418b31b931a9bb9af219fa
parent: bb1ab36108942ed9b0c84bf68e22869994467a2a
author: Simon Tatham <anakin@pobox.com>
date: Sun Apr 23 06:09:27 EDT 2023
Universal preference option for one-key shortcuts. With this option turned off (it's on by default), the single-letter keyboard shortcuts like 'q' for quit and 'n' for new game don't function any more. You can still access the same functions via more complicated shortcuts like Ctrl-Q or Ctrl-N, and front ends can provide any other UI they like for the same operations, but this way, people aren't at risk of blowing away half an hour of puzzling with one misaimed key. This is a thing people have occasionally asked for, and I've generally resisted on the grounds that I have sympathy for people playing puzzles at work who need to be able to close the game quickly when an unsympathetic boss wanders by. But now we have a preferences system, we can cater to those people _and_ the ones who don't mind. More immediately useful: adding _at least one_ universal preference in the initial version of this system means that there will be no games with no preference options at all, and therefore, no need to put conditionals all through the participating frontends to deal with whether the Preferences menu option should even be provided. That would have been a waste of time because all those conditionals would just have to be removed again as soon as the first universal preference came along - so adding an easy one _now_ means we can save the effort of putting in the temporary conditionals in the first place.
--- a/midend.c
+++ b/midend.c
@@ -101,6 +101,8 @@
void (*game_id_change_notify_function)(void *);
void *game_id_change_notify_ctx;
+
+ bool one_key_shortcuts;
};
#define ensure(me) do { \
@@ -237,6 +239,8 @@
me->be_prefs.buf = NULL;
me->be_prefs.size = me->be_prefs.len = 0;
+ me->one_key_shortcuts = true;
+
midend_reset_tilesize(me);
sfree(randseed);
@@ -986,14 +990,14 @@
}
if (!movestr) {
- if (button == 'n' || button == 'N' || button == '\x0E' ||
- button == UI_NEWGAME) {
+ if ((me->one_key_shortcuts && (button == 'n' || button == 'N')) ||
+ button == '\x0E' || button == UI_NEWGAME) {
midend_new_game(me);
midend_redraw(me);
*handled = true;
goto done; /* never animate */
- } else if (button == 'u' || button == 'U' || button == '*' ||
- button == '\x1A' || button == '\x1F' ||
+ } else if ((me->one_key_shortcuts && (button=='u' || button=='U')) ||
+ button == '*' || button == '\x1A' || button == '\x1F' ||
button == UI_UNDO) {
midend_stop_anim(me);
type = me->states[me->statepos-1].movetype;
@@ -1001,8 +1005,8 @@
if (!midend_undo(me))
goto done;
*handled = true;
- } else if (button == 'r' || button == 'R' || button == '#' ||
- button == '\x12' || button == '\x19' ||
+ } else if ((me->one_key_shortcuts && (button=='r' || button=='R')) ||
+ button == '#' || button == '\x12' || button == '\x19' ||
button == UI_REDO) {
midend_stop_anim(me);
if (!midend_redo(me))
@@ -1013,8 +1017,8 @@
*handled = true;
if (midend_solve(me))
goto done;
- } else if (button == 'q' || button == 'Q' || button == '\x11' ||
- button == UI_QUIT) {
+ } else if ((me->one_key_shortcuts && (button=='q' || button=='Q')) ||
+ button == '\x11' || button == UI_QUIT) {
ret = false;
*handled = true;
goto done;
@@ -2901,11 +2905,18 @@
n_be_prefs++;
}
- n_me_prefs = 0;
+ n_me_prefs = 1;
all_prefs = snewn(n_me_prefs + n_be_prefs + 1, config_item);
pos = 0;
+ assert(pos < n_me_prefs);
+ all_prefs[pos].name = "Keyboard shortcuts without Ctrl";
+ all_prefs[pos].kw = "one-key-shortcuts";
+ all_prefs[pos].type = C_BOOLEAN;
+ all_prefs[pos].u.boolean.bval = me->one_key_shortcuts;
+ pos++;
+
for (i = 0; i < n_be_prefs; i++) {
all_prefs[pos] = be_prefs[i]; /* structure copy */
pos++;
@@ -2924,6 +2935,9 @@
{
int pos = 0;
game_ui *tmpui = NULL;
+
+ me->one_key_shortcuts = all_prefs[pos].u.boolean.bval;
+ pos++;
if (me->ourgame->get_prefs) {
if (!ui)