From 03cbd428f70d3b2907675de65df4fc8a217acf5e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 26 Jan 2025 22:15:49 -0800 Subject: [PATCH] Protect against GCing of last_mouse_window MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * src/window.c (last_mouse_window): New global var. All static instances removed, and all their uses replaced with this global var. This fixes a very unlikely bug where last_mouse_window was GC’ed and a new window created in its place. It also fixes several places that assumed NIL_IS_ZERO without static_asserting it. (init_window_once): Initialize the new var. (cherry picked from commit 2e8ef0910412aef8f9f1beba7c942473ad8602bb) --- src/androidterm.c | 1 - src/haikuterm.c | 1 - src/msdos.c | 2 -- src/pgtkterm.c | 1 - src/w32inevt.c | 1 - src/w32term.c | 1 - src/window.c | 6 ++++++ src/window.h | 4 ++++ src/xterm.c | 3 --- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/androidterm.c b/src/androidterm.c index 688f254ee23..e0f66652300 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -1179,7 +1179,6 @@ handle_one_android_event (struct android_display_info *dpyinfo, && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, event->xmotion.x, event->xmotion.y, 0, diff --git a/src/haikuterm.c b/src/haikuterm.c index 7f02de2ca15..4a217c9e0e2 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3562,7 +3562,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) if (!NILP (Vmouse_autoselect_window)) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, b->x, b->y, 0, 0, 0, 0); if (WINDOWP (window) diff --git a/src/msdos.c b/src/msdos.c index 95eb6453040..49403ba72f4 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -2677,8 +2677,6 @@ dos_rawgetc (void) /* Generate SELECT_WINDOW_EVENTs when needed. */ if (!NILP (Vmouse_autoselect_window)) { - static Lisp_Object last_mouse_window; - mouse_window = window_from_coordinates (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0, 0, 0); /* A window will be selected only when it is not diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 2da1006b6f7..0f272bbeac8 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -5938,7 +5938,6 @@ motion_notify_event (GtkWidget *widget, GdkEvent *event, also when the target window is on another frame. */ && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, event->motion.x, event->motion.y, 0, false, false, false); diff --git a/src/w32inevt.c b/src/w32inevt.c index 1c80f7c6db7..b0e6b5a9286 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -467,7 +467,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event, struct input_event *emacs_ev) { static DWORD button_state = 0; - static Lisp_Object last_mouse_window; DWORD but_change, mask, flags = event->dwEventFlags; int i; diff --git a/src/w32term.c b/src/w32term.c index cb7bc7e4540..5613ade01ce 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -5444,7 +5444,6 @@ w32_read_socket (struct terminal *terminal, || (!NILP (focus_follows_mouse) && !FRAME_NO_ACCEPT_FOCUS (f)))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 0, 0); diff --git a/src/window.c b/src/window.c index 0ed1b53d866..330a95a716f 100644 --- a/src/window.c +++ b/src/window.c @@ -106,6 +106,9 @@ Lisp_Object minibuf_window; shown as the selected window when the minibuffer is selected. */ Lisp_Object minibuf_selected_window; +/* Non-nil means it is the window containing the last mouse movement. */ +Lisp_Object last_mouse_window; + /* Incremented for each window created. */ static EMACS_INT sequence_number; @@ -8778,6 +8781,8 @@ init_window_once (void) minibuf_selected_window = Qnil; staticpro (&minibuf_selected_window); + last_mouse_window = Qnil; + staticpro (&last_mouse_window); old_selected_window = Qnil; staticpro (&old_selected_window); @@ -8796,6 +8801,7 @@ static void init_window_once_for_pdumper (void) PDUMPER_RESET_LV (selected_window, Qnil); PDUMPER_RESET_LV (Vwindow_list, Qnil); PDUMPER_RESET_LV (minibuf_selected_window, Qnil); + PDUMPER_RESET_LV (last_mouse_window, Qnil); /* Hack: if mode_line_in_non_selected_windows is true (which it may be, if we're restoring from a dump) the guts of diff --git a/src/window.h b/src/window.h index a48c370b198..2266fc7814c 100644 --- a/src/window.h +++ b/src/window.h @@ -1116,6 +1116,10 @@ extern Lisp_Object minibuf_window; extern Lisp_Object minibuf_selected_window; +/* Non-nil means it is the window containing the last mouse movement. */ + +extern Lisp_Object last_mouse_window; + extern Lisp_Object make_window (void); extern Lisp_Object window_from_coordinates (struct frame *, int, int, enum window_part *, bool, bool, bool); diff --git a/src/xterm.c b/src/xterm.c index fd61d5df91c..e024b36daf5 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -21291,8 +21291,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; - if (xmotion.window != FRAME_X_WINDOW (f)) { x_translate_coordinates (f, xmotion.x_root, xmotion.y_root, @@ -23231,7 +23229,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false, false); -- 2.39.5