From d5658018ac8806c2a00c96f89d878c4834b07fa3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 8 Nov 2025 14:26:07 -0500 Subject: [PATCH] alternative to display_inventory for window-port Several window ports that support perm_invent were using a call back to the core display_inventory() function. While calling from the window port back to core functions is arguably not ideal in the first place, it was recently brought to light that code NetHack-3.7 code changes to display_inventory() actually caused it to stop repopulating the perm_invent window as intended under certain circumstances. For now, provide an alternative function, repopulate_perminvent(), that hopefullshould still work the way it did previously. There will likely be some additional changes after this to further improve things, at some point. For now though, this Resolves #1454 --- doc/window.txt | 6 +++++- include/extern.h | 1 + src/invent.c | 7 +++++++ win/Qt/qt_bind.cpp | 2 +- win/X11/winX.c | 2 +- win/curses/cursinvt.c | 2 +- win/shim/winshim.c | 6 +++--- win/win32/mswproc.c | 4 ++-- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/doc/window.txt b/doc/window.txt index 45593eb88..d2f55793a 100644 --- a/doc/window.txt +++ b/doc/window.txt @@ -284,7 +284,7 @@ update_inventory(arg) -- For an argument of 0: -- Indicate to the window port that the inventory has been changed. - -- Merely calls display_inventory() for window-ports + -- Merely calls repopulate_perminvent() for window-ports that leave the window up, otherwise empty. -- or for a non-zero argument: -- Prompts the user for a menu scrolling action and @@ -1001,6 +1001,10 @@ char display_inventory(lets, want_reply) -- Calls a start_menu()/add_menu()/select_menu() sequence. It returns the item selected, or '\0' if none is selected. Returns '\033' if the menu was canceled. +void repopulate_perminvent(void) + -- a minimal alternative to display_inventory() that + focuses only on repopulating the permanent inventory + window. raw_printf(str, ...) -- Like raw_print(), but accepts arguments like printf(). This routine processes the arguments and then calls raw_print(). diff --git a/include/extern.h b/include/extern.h index 247cc8e15..6fe005940 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1358,6 +1358,7 @@ extern void sync_perminvent(void); extern void perm_invent_toggled(boolean negated); extern void prepare_perminvent(winid window); extern struct obj *carrying_stoning_corpse(void); +extern void repopulate_perminvent(void); /* ### ioctl.c ### */ diff --git a/src/invent.c b/src/invent.c index 5d62567f2..37b23a87f 100644 --- a/src/invent.c +++ b/src/invent.c @@ -4047,6 +4047,13 @@ display_inventory(const char *lets, boolean want_reply) FALSE, want_reply, (long *) 0); } +void +repopulate_perminvent(void) +{ + (void) display_pickinv(NULL, (char *) 0, (char *) 0, + FALSE, FALSE, (long *) 0); +} + /* * Show what is current using inventory letters. * diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 58dc96476..fd55061e2 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -502,7 +502,7 @@ void NetHackQtBind::qt_update_inventory(int arg UNUSED) /* doesn't work yet if (program_state.something_worth_saving && iflags.perm_invent) - display_inventory(NULL, false); + repopulate_perminvent(); */ } diff --git a/win/X11/winX.c b/win/X11/winX.c index 1021c6ce3..f74408269 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1295,7 +1295,7 @@ X11_update_inventory(int arg) if (program_state.in_moveloop || program_state.gameover) { updated_inventory = 1; /* hack to avoid mapping&raising window */ if (!arg) { - (void) display_inventory((char *) 0, FALSE); + repopulate_perminvent(); } else { x11_scroll_perminv(arg); } diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 4095ceb5a..1aadad9f9 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -96,7 +96,7 @@ curs_update_invt(int arg) /* ask core to display full inventory in a PICK_NONE menu; instead of setting up an ordinary menu, it will indirectly call curs_add_invt() for each line (including class headers) */ - display_inventory(NULL, FALSE); + repopulate_perminvent(); curs_invt_updated(win); } else { diff --git a/win/shim/winshim.c b/win/shim/winshim.c index fdbe18b9e..5e701c332 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -172,11 +172,11 @@ VDECLCB(shim_status_update, "vipiiip", A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks) #ifdef __EMSCRIPTEN__ -/* XXX: calling display_inventory() from shim_update_inventory() causes reentrancy that breaks emscripten Asyncify */ -/* this should be fine since according to windows.doc, the only purpose of shim_update_inventory() is to call display_inventory() */ +/* XXX: calling repopulate_perminvent() from shim_update_inventory() causes reentrancy that breaks emscripten Asyncify */ +/* this should be fine since according to windows.doc, the only purpose of shim_update_inventory() is to call repopulate_perminvent() */ void shim_update_inventory(int a1 UNUSED) { if(iflags.perm_invent) { - display_inventory(NULL, FALSE); + repopulate_perminvent(); } } diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 06464c6de..abef776da 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1248,7 +1248,7 @@ mswin_select_menu(winid wid, int how, MENU_ITEM_P **selected) /* -- Indicate to the window port that the inventory has been changed. - -- Merely calls display_inventory() for window-ports that leave the + -- Merely calls repopulate_perminvent() for window-ports that leave the window up, otherwise empty. */ void @@ -1257,7 +1257,7 @@ mswin_update_inventory(int arg) logDebug("mswin_update_inventory(%d)\n", arg); if (iflags.perm_invent && program_state.something_worth_saving && iflags.window_inited && WIN_INVEN != WIN_ERR) - display_inventory(NULL, FALSE); + repopulate_perminvent(); } win_request_info *