Subject: Re: bug#61525: 29.0.60; delete-frame will raise frames in another virtual desktop

From: Daniel Martín <[email-masked]>
Date: Wed, 15 Feb 2023 16:41:41 +0100

Daniel Martín via "Bug reports for GNU Emacs, the Swiss army knife of
text editors" <[email-masked]> writes:

>
> One downside of removing raise_frame is that, after you press C-x 5 0,
> you cannot start typing right away without first focusing on another
> Emacs frame manually.  People would consider this a regression from
> previous versions and something that doesn't happen on GNU/Linux.
>
> A possibly better approach could be:
>
> Once the "other" frame to select is chosen by the code that is just
> above in frame.c, call some Obj-C code that extracts the EmacsView and
> makes it the first responder:
>
> EmacsView *view = FRAME_NS_VIEW (frame1);
> [self makeFirstResponder:view];
>
> I haven't tested this, but perhaps this makes the other frame receive
> focus without switching desktops in a multi-desktop configuration.

The attached patch avoids the unwanted side effects of raise-frame by
making the other frame the key window, instead.  Could you give it a
try?

>From 50cb6ed653b17bb5f712872f3f664e1273e498d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Mart=C3=ADn?= <[email-masked]>
Date: Wed, 15 Feb 2023 16:33:14 +0100
Subject: [PATCH] [NS] Do not raise a different frame when closing a frame

* src/frame.h: Declare an NS-only function to make a frame the key
window.
* src/nsfns.m (ns_make_frame_key_window): Implement it.
* src/frame.c (delete_frame): Call ns_make_frame_key_window instead of
Fraise_frame.  (Bug#61525)
---
 src/frame.c | 5 ++---
 src/frame.h | 5 +++++
 src/nsfns.m | 5 +++++
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/frame.c b/src/frame.c
index 983424b0bee..b2319a35aed 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2152,9 +2152,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
 	/* Under NS, there is no system mechanism for choosing a new
 	   window to get focus -- it is left to application code.
 	   So the portion of THIS application interfacing with NS
-	   needs to know about it.  We call Fraise_frame, but the
-	   purpose is really to transfer focus.  */
-	Fraise_frame (frame1);
+	   needs to make the frame we switch to the key window.  */
+	ns_make_frame_key_window (XFRAME (frame1));
 #endif
 
       do_switch_frame (frame1, 1, Qnil);
diff --git a/src/frame.h b/src/frame.h
index b95b94c7685..2eb9de81f0a 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1380,6 +1380,11 @@ window_system_available (struct frame *f)
 extern void frame_size_history_plain (struct frame *, Lisp_Object);
 extern void frame_size_history_extra (struct frame *, Lisp_Object,
 				      int, int, int, int, int, int);
+#ifdef NS_IMPL_COCOA
+/* Implemented in nsfns.m.  */
+extern void ns_make_frame_key_window (struct frame *f);
+#endif
+
 extern Lisp_Object Vframe_list;
 
 /* Value is a pointer to the selected frame.  If the selected frame
diff --git a/src/nsfns.m b/src/nsfns.m
index 8804a7df7cf..cd41c6095a0 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -685,6 +685,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   SET_FRAME_GARBAGED (f);
 }
 
+void ns_make_frame_key_window (struct frame *f)
+{
+  [[FRAME_NS_VIEW (f) window] makeKeyWindow];
+}
+
 /* tabbar support */
 static void
 ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
-- 
2.34.1