From eb4d09871740fbcac1bd6669134283bd22f59b03 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 3 Jun 2026 18:58:12 +0300 Subject: [PATCH] X11: Obey timed_delay I noticed a strange thing where the X11 windowport didn't show the tethered thrown aklys animation correctly. Interestingly, other stuff, such as zapped wands did show the path. I didn't bother trying to figure out what the core was doing differently, as the animation worked in all the other windowports, so instead fix the issue in X11, so it behaves the same as all the others. The issue seems to be that the event loop exited on any(?) event, instead of our specific timed event. So, create our event with a magic id number, and exit only when we encounter that. Also: Obey the timed_delay option, and change the delay from 30ms to 50ms, like in other windowports. --- doc/fixes5-0-1.txt | 1 + include/winX.h | 2 ++ win/X11/winX.c | 13 ++++++++----- win/X11/winmap.c | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index faec1ddd3..cf4641a86 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -172,6 +172,7 @@ Windows: with SELECTSAVE don't display error messages to a regular player dealt with external to the game, so try not to annoy tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors +X11: obey timed_delay General New Features diff --git a/include/winX.h b/include/winX.h index 495a2d29f..e26faf5b8 100644 --- a/include/winX.h +++ b/include/winX.h @@ -287,6 +287,8 @@ struct xwindow { * and dumplog message history */ #define YN_NO_DEFAULT 2U /* don't convert quitchars to 0 or ESC to q/n/def */ +#define DELAY_EVENT_ID 66 /* arbitrary byte value */ + /* Window variables (winX.c). */ extern struct xwindow window_list[MAX_WINDOWS]; extern XtAppContext app_context; /* context of application */ diff --git a/win/X11/winX.c b/win/X11/winX.c index 24fb4fcff..f4725399b 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1750,6 +1750,7 @@ d_timeout(XtPointer client_data, XtIntervalId *id) mesg->type = ClientMessage; mesg->message_type = XA_STRING; mesg->format = 8; + mesg->data.b[0] = DELAY_EVENT_ID; XSendEvent(XtDisplay(window_list[WIN_MAP].w), XtWindow(window_list[WIN_MAP].w), False, NoEventMask, (XEvent *) mesg); @@ -1766,11 +1767,13 @@ X11_delay_output(void) { if (!x_inited) return; - - (void) XtAppAddTimeOut(app_context, 30L, d_timeout, (XtPointer) 0); - - /* The timeout function will enable the event loop exit. */ - (void) x_event(EXIT_ON_SENT_EVENT); +#ifdef TIMED_DELAY + if (flags.nap && !iflags.debug_fuzzer) { + (void) XtAppAddTimeOut(app_context, 50L, d_timeout, (XtPointer) 0); + /* The timeout function will enable the event loop exit. */ + (void) x_event(EXIT_ON_SENT_EVENT); + } +#endif } /* X11_hangup ------------------------------------------------------------- */ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 7c2dbfcac..97e17eaee 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1969,9 +1969,9 @@ x_event(int exit_condition) try_test: switch (exit_condition) { case EXIT_ON_SENT_EVENT: { - XAnyEvent *any = (XAnyEvent *) &event; + XClientMessageEvent *cle = (XClientMessageEvent *) &event; - if (any->send_event) { + if (cle->send_event && cle->data.b[0] == DELAY_EVENT_ID) { retval = 0; keep_going = FALSE; }