diff options
| author | Pip Cet | 2026-04-10 11:59:23 +0000 |
|---|---|---|
| committer | Pip Cet | 2026-04-10 18:16:54 +0000 |
| commit | c05037ba1cddb20fee7446c4b2c73deb310b194c (patch) | |
| tree | e139489f0ec7c254a3a6e8d28d7aa868604e36ca /src | |
| parent | 2edcc6d4223a2837e594ff83c13832533b5e3ef8 (diff) | |
| download | emacs-c05037ba1cddb20fee7446c4b2c73deb310b194c.tar.gz emacs-c05037ba1cddb20fee7446c4b2c73deb310b194c.zip | |
Don't continue FOR_EACH_FRAME loops after delete_frame (bug#80789)
* src/xterm.c (x_connection_closed, x_delete_terminal): Restart
FOR_EACH_FRAME loops after deleting one (or potentially more) frames.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/xterm.c b/src/xterm.c index 48fb78a6f63..b02380a7171 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -26861,6 +26861,7 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) | |||
| 26861 | 26861 | ||
| 26862 | /* First delete frames whose mini-buffers are on frames | 26862 | /* First delete frames whose mini-buffers are on frames |
| 26863 | that are on the dead display. */ | 26863 | that are on the dead display. */ |
| 26864 | delete_more_minibuffer_frames: | ||
| 26864 | FOR_EACH_FRAME (tail, frame) | 26865 | FOR_EACH_FRAME (tail, frame) |
| 26865 | { | 26866 | { |
| 26866 | /* Tooltip frames don't have these, so avoid crashing. */ | 26867 | /* Tooltip frames don't have these, so avoid crashing. */ |
| @@ -26875,12 +26876,16 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) | |||
| 26875 | && FRAME_X_P (XFRAME (minibuf_frame)) | 26876 | && FRAME_X_P (XFRAME (minibuf_frame)) |
| 26876 | && ! EQ (frame, minibuf_frame) | 26877 | && ! EQ (frame, minibuf_frame) |
| 26877 | && FRAME_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo) | 26878 | && FRAME_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo) |
| 26878 | delete_frame (frame, Qnoelisp); | 26879 | { |
| 26880 | delete_frame (frame, Qnoelisp); | ||
| 26881 | goto delete_more_minibuffer_frames; | ||
| 26882 | } | ||
| 26879 | } | 26883 | } |
| 26880 | 26884 | ||
| 26881 | /* Now delete all remaining frames on the dead display. | 26885 | /* Now delete all remaining frames on the dead display. |
| 26882 | We are now sure none of these is used as the mini-buffer | 26886 | We are now sure none of these is used as the mini-buffer |
| 26883 | for another frame that we need to delete. */ | 26887 | for another frame that we need to delete. */ |
| 26888 | delete_more_frames: | ||
| 26884 | FOR_EACH_FRAME (tail, frame) | 26889 | FOR_EACH_FRAME (tail, frame) |
| 26885 | if (FRAME_X_P (XFRAME (frame)) | 26890 | if (FRAME_X_P (XFRAME (frame)) |
| 26886 | && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) | 26891 | && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) |
| @@ -26889,6 +26894,7 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) | |||
| 26889 | trying to find a replacement. */ | 26894 | trying to find a replacement. */ |
| 26890 | kset_default_minibuffer_frame (FRAME_KBOARD (XFRAME (frame)), Qt); | 26895 | kset_default_minibuffer_frame (FRAME_KBOARD (XFRAME (frame)), Qt); |
| 26891 | delete_frame (frame, Qnoelisp); | 26896 | delete_frame (frame, Qnoelisp); |
| 26897 | goto delete_more_frames; | ||
| 26892 | } | 26898 | } |
| 26893 | 26899 | ||
| 26894 | /* If DPYINFO is null, this means we didn't open the display in the | 26900 | /* If DPYINFO is null, this means we didn't open the display in the |
| @@ -32029,13 +32035,17 @@ x_delete_terminal (struct terminal *terminal) | |||
| 32029 | /* Delete all remaining frames on the display that is going away. | 32035 | /* Delete all remaining frames on the display that is going away. |
| 32030 | Otherwise, font backends assume the display is still up, and | 32036 | Otherwise, font backends assume the display is still up, and |
| 32031 | xftfont_end_for_frame crashes. */ | 32037 | xftfont_end_for_frame crashes. */ |
| 32038 | delete_more_frames: | ||
| 32032 | FOR_EACH_FRAME (tail, frame) | 32039 | FOR_EACH_FRAME (tail, frame) |
| 32033 | { | 32040 | { |
| 32034 | f = XFRAME (frame); | 32041 | f = XFRAME (frame); |
| 32035 | 32042 | ||
| 32036 | if (FRAME_LIVE_P (f) && f->terminal == terminal) | 32043 | if (FRAME_LIVE_P (f) && f->terminal == terminal) |
| 32037 | /* Pass Qnoelisp rather than Qt. */ | 32044 | { |
| 32038 | delete_frame (frame, Qnoelisp); | 32045 | /* Pass Qnoelisp rather than Qt. */ |
| 32046 | delete_frame (frame, Qnoelisp); | ||
| 32047 | goto delete_more_frames; | ||
| 32048 | } | ||
| 32039 | } | 32049 | } |
| 32040 | 32050 | ||
| 32041 | #ifdef HAVE_X_I18N | 32051 | #ifdef HAVE_X_I18N |