aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2025-07-09 09:52:01 +0200
committerMartin Rudalics2025-07-09 09:52:01 +0200
commit2fc402cb0bb62f3c401528246742501a8d42bf14 (patch)
treef6fcb1c057926cd4b9cb0e5637a159b3ea0acf0d
parent280d6f70a356dc24a7026c00cbcbd116c2f7c7ed (diff)
downloademacs-2fc402cb0bb62f3c401528246742501a8d42bf14.tar.gz
emacs-2fc402cb0bb62f3c401528246742501a8d42bf14.zip
Handle invalid frame_or_window slots in tty input events (Bug#78966)
* src/frame.c (make_terminal_frame): Initialize terminal's top_frame slot if it has not been set up yet (Bug#78966). * src/keyboard.c (kbd_buffer_get_event): Do not assume that the event's frame_or_window slot always produces a valid frame (Bug#78966). (tty_read_avail_input): Try to make sure that the input event we create has a valid frame_or_window slot (Bug#78966). Add assertion to that purpose.
-rw-r--r--src/frame.c9
-rw-r--r--src/keyboard.c35
2 files changed, 34 insertions, 10 deletions
diff --git a/src/frame.c b/src/frame.c
index 95fcb9ca7ff..70e200d9219 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1449,6 +1449,15 @@ make_terminal_frame (struct terminal *terminal, Lisp_Object parent,
1449 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR; 1449 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
1450#endif /* not MSDOS */ 1450#endif /* not MSDOS */
1451 1451
1452 struct tty_display_info *tty = terminal->display_info.tty;
1453
1454 if (NILP (tty->top_frame))
1455 /* If this frame's terminal's top frame has not been set up yet,
1456 make the new frame its top frame so the top frame has been set up
1457 before the first do_switch_frame on this terminal happens. See
1458 Bug#78966. */
1459 tty->top_frame = frame;
1460
1452#ifdef HAVE_WINDOW_SYSTEM 1461#ifdef HAVE_WINDOW_SYSTEM
1453 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 1462 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
1454 f->horizontal_scroll_bars = false; 1463 f->horizontal_scroll_bars = false;
diff --git a/src/keyboard.c b/src/keyboard.c
index fcb66f4c58a..b389d98feaa 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4281,22 +4281,29 @@ kbd_buffer_get_event (KBOARD **kbp,
4281 break; 4281 break;
4282 default: 4282 default:
4283 { 4283 {
4284 /* If this event is on a different frame, return a
4285 switch-frame this time, and leave the event in the queue
4286 for next time. */
4287 Lisp_Object frame; 4284 Lisp_Object frame;
4288 Lisp_Object focus; 4285 Lisp_Object focus;
4289 4286
4287 /* It's not safe to assume that the following will always
4288 produce a valid, live frame (Bug#78966). */
4290 frame = event->ie.frame_or_window; 4289 frame = event->ie.frame_or_window;
4291 if (CONSP (frame)) 4290 if (CONSP (frame))
4292 frame = XCAR (frame); 4291 frame = XCAR (frame);
4293 else if (WINDOWP (frame)) 4292 else if (WINDOWP (frame))
4294 frame = WINDOW_FRAME (XWINDOW (frame)); 4293 frame = WINDOW_FRAME (XWINDOW (frame));
4295 4294
4296 focus = FRAME_FOCUS_FRAME (XFRAME (frame)); 4295 /* If the input focus of this frame is on another frame,
4297 if (! NILP (focus)) 4296 continue with that frame. */
4298 frame = focus; 4297 if (FRAMEP (frame))
4298 {
4299 focus = FRAME_FOCUS_FRAME (XFRAME (frame));
4300 if (! NILP (focus))
4301 frame = focus;
4302 }
4299 4303
4304 /* If this event is on a different frame, return a
4305 switch-frame this time, and leave the event in the queue
4306 for next time. */
4300 if (!EQ (frame, internal_last_event_frame) 4307 if (!EQ (frame, internal_last_event_frame)
4301 && !EQ (frame, selected_frame)) 4308 && !EQ (frame, selected_frame))
4302 obj = make_lispy_switch_frame (frame); 4309 obj = make_lispy_switch_frame (frame);
@@ -8245,13 +8252,21 @@ tty_read_avail_input (struct terminal *terminal,
8245 value of selected_frame is not reliable here, redisplay tends 8252 value of selected_frame is not reliable here, redisplay tends
8246 to temporarily change it. However, if the selected frame is a 8253 to temporarily change it. However, if the selected frame is a
8247 child frame, don't do that since it will cause switch frame 8254 child frame, don't do that since it will cause switch frame
8248 events to switch to the root frame instead. */ 8255 events to switch to the root frame instead. If the tty's top
8249 if (FRAME_PARENT_FRAME (XFRAME (selected_frame)) 8256 frame has not been set up yet, always use the selected frame
8250 && (root_frame (XFRAME (selected_frame)) 8257 (Bug#78966). */
8251 == XFRAME (tty->top_frame))) 8258 if (!FRAMEP (tty->top_frame)
8259 || (FRAME_PARENT_FRAME (XFRAME (selected_frame))
8260 && (root_frame (XFRAME (selected_frame))
8261 == XFRAME (tty->top_frame))))
8252 buf.frame_or_window = selected_frame; 8262 buf.frame_or_window = selected_frame;
8253 else 8263 else
8254 buf.frame_or_window = tty->top_frame; 8264 buf.frame_or_window = tty->top_frame;
8265
8266 /* If neither the selected frame nor the top frame were set,
8267 something must have gone really wrong. */
8268 eassert (FRAMEP (buf.frame_or_window));
8269
8255 buf.arg = Qnil; 8270 buf.arg = Qnil;
8256 8271
8257 kbd_buffer_store_event (&buf); 8272 kbd_buffer_store_event (&buf);