From 5fd7a5cc96a19d2af9cd4da26505ba5523a5d9ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gerd=20M=C3=B6llmann?= Date: Sat, 25 Jan 2025 14:28:18 +0100 Subject: [PATCH] Reapply "Multi-tty: selected frame can be a GUI frame" This reverts commit d93d822285813b89f2444ef93c5747cbeb67a46b. (cherry picked from commit 20f26723774d50292f21487fb21b92355444d678) --- src/dispnew.c | 53 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/src/dispnew.c b/src/dispnew.c index ebca32ae30e..ac1805a4489 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3903,26 +3903,44 @@ is_in_matrix (struct frame *f, int x, int y) return true; } -/* Is the terminal cursor of the selected frame obscured by a child - frame? */ +/* Return the frame of the selected window of frame F. + Value is NULL if we can't tell. */ + +static struct frame * +frame_selected_window_frame (struct frame *f) +{ + /* Paranoia. It should not happen that window or frame not valid. */ + Lisp_Object frame; + if (WINDOWP (f->selected_window) + && (frame = XWINDOW (f->selected_window)->frame, + FRAMEP (frame))) + return XFRAME (frame); + return NULL; +} + +/* Is the terminal cursor of ROOT obscured by a child frame? */ static bool -is_cursor_obscured (void) +is_cursor_obscured (struct frame *root) { + /* Determine in which frame on ROOT the cursor could be. */ + struct frame *sf = frame_selected_window_frame (root); + if (sf == NULL) + return false; + /* Give up if we can't tell where the cursor currently is. */ int x, y; - if (!abs_cursor_pos (SELECTED_FRAME (), &x, &y)) + if (!abs_cursor_pos (sf, &x, &y)) return false; /* (x, y) may be outside of the root frame in case the selected frame is a child frame which is clipped. */ - struct frame *root = root_frame (SELECTED_FRAME ()); if (!is_in_matrix (root, x, y)) return true; struct glyph_row *cursor_row = MATRIX_ROW (root->current_matrix, y); struct glyph *cursor_glyph = cursor_row->glyphs[0] + x; - return cursor_glyph->frame != SELECTED_FRAME (); + return cursor_glyph->frame != sf; } /* Decide where to show the cursor, and whether to hide it. @@ -3936,7 +3954,7 @@ static void terminal_cursor_magic (struct frame *root, struct frame *topmost_child) { /* By default, prevent the cursor "shining through" child frames. */ - if (is_cursor_obscured ()) + if (is_cursor_obscured (root)) tty_hide_cursor (FRAME_TTY (root)); /* If the terminal cursor is not in the topmost child, the topmost @@ -3944,7 +3962,8 @@ terminal_cursor_magic (struct frame *root, struct frame *topmost_child) non-nil, display the cursor in this "non-selected" topmost child frame to compensate for the fact that we can't display a non-selected cursor like on a window system frame. */ - if (topmost_child != SELECTED_FRAME ()) + struct frame *sf = frame_selected_window_frame (root); + if (sf && topmost_child != sf) { Lisp_Object frame; XSETFRAME (frame, topmost_child); @@ -3956,25 +3975,23 @@ terminal_cursor_magic (struct frame *root, struct frame *topmost_child) if (is_in_matrix (root, x, y)) { cursor_to (root, y, x); - tty_show_cursor (FRAME_TTY (topmost_child)); + tty_show_cursor (FRAME_TTY (root)); } else tty_hide_cursor (FRAME_TTY (root)); - } + } } } -#endif /* !HAVE_ANDROID */ - void combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) { -#ifndef HAVE_ANDROID struct frame *root = root_frame (f); /* Determine visible frames on the root frame, including the root frame itself. Note that there are cases, see bug#75056, where we - can be called for invisible frames. */ + can be called for invisible frames. This looks like a bug with + multi-tty, but the old update code didn't check visibility either. */ Lisp_Object z_order = frames_in_reverse_z_order (root, true); if (NILP (z_order)) { @@ -4015,9 +4032,15 @@ combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) add_frame_display_history (f, false); #endif } -#endif /* HAVE_ANDROID */ } +#else /* HAVE_ANDROID */ +void +combine_updates_for_frame (struct frame *f, bool inhibit_scrolling) +{ +} +#endif /* HAVE_ANDROID */ + /* Update on the screen all root frames ROOTS. Called from redisplay_internal as the last step of redisplaying. */ -- 2.39.5