From: PatR Date: Tue, 16 Mar 2021 16:13:55 +0000 (-0700) Subject: X11 perm_invent positioning X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b3d21fd337891f61013d30d4c1df778dbab5e119;p=nethack X11 perm_invent positioning Change the '|'/#perminv final positioning for X11 to be the same as for curses: finishing with leaves the current view, with 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.) --- diff --git a/include/winX.h b/include/winX.h index 06a6409e9..c6c1dce73 100644 --- a/include/winX.h +++ b/include/winX.h @@ -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]; diff --git a/win/X11/winX.c b/win/X11/winX.c index 97bbab271..804ef2ba8 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -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 */ diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 438b89ae6..890dc33ae 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -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; }