]> granicus.if.org Git - nethack/commitdiff
X11 perm_invent positioning
authorPatR <rankin@nethack.org>
Tue, 16 Mar 2021 16:13:55 +0000 (09:13 -0700)
committerPatR <rankin@nethack.org>
Tue, 16 Mar 2021 16:13:55 +0000 (09:13 -0700)
Change the '|'/#perminv final positioning for X11 to be the same
as for curses:  finishing with <escape> leaves the current view,
with <return> resets to unscrolled.

Actually getting ESC and RET to the right place wasn't trivial;
down the rabbit hole and out the other side.  Using yn_function()
to get the #perminv keystrokes is less than ideal.  (curses also
started that way but switched to raw character input for this.)

include/winX.h
win/X11/winX.c
win/X11/winmenu.c

index 06a6409e9d81a6c802085a99bcb9e81c718dfd11..c6c1dce73a7089f0806e1716ea950287b563f8ef 100644 (file)
@@ -257,6 +257,7 @@ struct xwindow {
 #define YN_NORMAL     0U /* no flags */
 #define YN_NO_LOGMESG 1U /* suppress echo of prompt+response to message window
                           * and dumplog message history */
+#define YN_NO_DEFAULT 2U /* don't convert quitchars to 0 or ESC to q/n/def */
 
 /* Window variables (winX.c). */
 extern struct xwindow window_list[MAX_WINDOWS];
index 97bbab271f9cba4af0b34de092c776f5fa233bb3..804ef2ba89b8432361b8b6d9e6cb6806277cf9df 100644 (file)
@@ -2029,6 +2029,7 @@ static Widget yn_popup;          /* popup for the yn fuction (created once) */
 static Widget yn_label;          /* label for yn function (created once) */
 static boolean yn_getting_num;   /* TRUE if accepting digits */
 static boolean yn_preserve_case; /* default is to force yn to lower case */
+static boolean yn_no_default;    /* don't convert ESC or quitchars to def */
 static int yn_ndigits;           /* digit count */
 static long yn_val;              /* accumulated value */
 
@@ -2094,7 +2095,8 @@ yn_key(Widget w, XEvent *event, String *params, Cardinal *num_params)
         return;
     }
 
-    if (!yn_choices) { /* accept any input */
+    if (!yn_choices /* accept any input */
+        || (yn_no_default && (ch == '\033' || index(yn_quitchars, ch)))) {
         yn_return = ch;
     } else {
         if (!yn_preserve_case)
@@ -2170,10 +2172,12 @@ X11_yn_function_core(
     char buf[BUFSZ], buf2[BUFSZ];
     Arg args[4];
     Cardinal num_args;
-    boolean suppress_logging = (ynflags & YN_NO_LOGMESG) != 0U;
+    boolean suppress_logging = (ynflags & YN_NO_LOGMESG) != 0U,
+            no_default_cnvrt = (ynflags & YN_NO_DEFAULT) != 0U;
 
     yn_choices = choices; /* set up globals for callback to use */
     yn_def = def;
+    yn_no_default = no_default_cnvrt;
     yn_preserve_case = !choices; /* preserve case when an arbitrary
                                   * response is allowed */
 
index 438b89ae6c9828399bbe3a68daf89264fa9edc56..890dc33aea8392b1754e48e99d0a268d8349919b 100644 (file)
@@ -53,6 +53,7 @@ static void invert_all(struct xwindow *);
 static void invert_match(struct xwindow *, char *);
 static void menu_popdown(struct xwindow *);
 static unsigned menu_scrollmask(struct xwindow *);
+static void menu_unscroll(struct xwindow *);
 static Widget menu_create_buttons(struct xwindow *, Widget, Widget);
 static void menu_create_entries(struct xwindow *, struct menu *);
 static void destroy_menu_entry_widgets(struct xwindow *);
@@ -256,7 +257,7 @@ menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params)
 
         ch = map_menu_cmd(ch);
         if (ch == '\033') { /* quit */
-            if (menu_info->counting) {
+            if (menu_info->counting || perminv_scrolling) {
                 /* when there's a count in progress, ESC discards it
                    rather than dismissing the whole menu */
                 reset_menu_count(menu_info);
@@ -264,6 +265,10 @@ menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params)
             }
             select_none(wp);
         } else if (ch == '\n' || ch == '\r') {
+            if (perminv_scrolling) {
+                menu_unscroll(wp);
+                return; /* skip menu_popdown() */
+            }
             ; /* accept */
         } else if (digit(ch)) {
             /* special case: '0' is also the default ball class */
@@ -625,6 +630,31 @@ menu_scrollmask(struct xwindow *wp)
     return scrlmask;
 }
 
+/* if a menu is scrolled vertically and/horizontallty, return it to the top
+   and far left */
+static void
+menu_unscroll(struct xwindow *wp)
+{
+    float top, left, zero = 0.0;
+    Arg arg;
+    Widget hbar = (Widget) 0, vbar = (Widget) 0;
+
+    find_scrollbars(wp->w, wp->popup, &hbar, &vbar);
+    if (hbar) {
+        XtSetArg(arg, nhStr(XtNtopOfThumb), &left);
+        XtGetValues(hbar, &arg, ONE);
+        if (left > 0.0)
+            XtCallCallbacks(hbar, XtNjumpProc, &zero);
+    }
+    if (vbar) {
+        XtSetArg(arg, nhStr(XtNtopOfThumb), &top);
+        XtGetValues(vbar, &arg, ONE);
+        if (top > 0.0)
+            XtCallCallbacks(vbar, XtNjumpProc, &zero);
+    }
+    return;
+}
+
 /* Global functions ======================================================= */
 
 /* called by X11_update_inventory() if persistent inventory is currently
@@ -684,7 +714,7 @@ x11_scroll_perminv(int arg UNUSED) /* arg is always 1 */
         save_is_active = wp->menu_information->is_active;
         wp->menu_information->is_active = TRUE;
         ch = X11_yn_function_core("Inventory scroll:", menukeys,
-                                  0, YN_NO_LOGMESG);
+                                  0, (YN_NO_LOGMESG | YN_NO_DEFAULT));
         if (wp->menu_information->is_up)
             wp->menu_information->is_active = save_is_active;
         else
@@ -705,8 +735,7 @@ x11_scroll_perminv(int arg UNUSED) /* arg is always 1 */
                favor of easy to handle union type code; might conceivably
                confuse a sophisticated debugger so we should possibly redo
                this to set it up properly:  event->keyevent->keycode */
-            fake_perminv_event.type = !index(quitchars, ch) ? ch
-                                      : MENU_FIRST_PAGE;
+            fake_perminv_event.type = ch;
             menu_key(wp->w, &fake_perminv_event, (String *) 0, &no_args);
             fake_perminv_event.type = 0;
         }