master 6f27a2edbaa: Fix ‘read-minibuffer-re store-windows’ and 'focus-follows-mouse' behaviors

Martin Rudalics via Mailing list for Emacs changes <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: master
commit 6f27a2edbaa5f144a4db8f51bfa178b6c431812c
Author: Martin Rudalics <[email protected]>
Commit: Martin Rudalics <[email protected]>

    Fix ‘read-minibuffer-restore-windows’ and 'focus-follows-mouse' behaviors
    
    * src/window.c (Fset_window_configuration): When
    'focus-follows-mouse' equals 'auto-raise', explicitly select the
    frame and set its input focus if necessary.
    (restore_focus_frame): New function.
    * src/window.h (restore_focus_frame): Add declaration.
    * src/minibuf.c (read_minibuf): Restore frame focus also when
    'read-minibuffer-restore-windows' is nil.
    * src/xterm.c (x_focus_frame): Don't use window manager activation
    when 'focus-follows-mouse' equals 'auto-raise'.
---
 src/minibuf.c | 28 +++++++++++++++++-----------
 src/window.c  | 31 ++++++++++++++++++++++++++++++-
 src/window.h  |  1 +
 src/xterm.c   | 10 ++++++++--
 4 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/src/minibuf.c b/src/minibuf.c
index 745a71a63fc..8f0297adf0b 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -693,17 +693,23 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
 
   record_unwind_protect_void (minibuffer_unwind);
   if (read_minibuffer_restore_windows)
-    record_unwind_protect (restore_window_configuration,
-			   list3 (Fcurrent_window_configuration (Qnil),
-				  Qt, Qt));
-
-  /* If the minibuffer window is on a different frame, save that
-     frame's configuration too.  */
-  if (read_minibuffer_restore_windows &&
-      !EQ (mini_frame, selected_frame))
-    record_unwind_protect (restore_window_configuration,
-			   list3 (Fcurrent_window_configuration (mini_frame),
-				  Qnil, Qt));
+    {
+      record_unwind_protect
+	(restore_window_configuration,
+	 list3 (Fcurrent_window_configuration (Qnil), Qt, Qt));
+
+      /* If the minibuffer window is on a different frame, save that
+	 frame's configuration too.  */
+      if (!EQ (mini_frame, selected_frame))
+	record_unwind_protect
+	  (restore_window_configuration,
+	   list3 (Fcurrent_window_configuration (mini_frame), Qnil, Qt));
+    }
+  else if (!EQ (mini_frame, selected_frame))
+    record_unwind_protect
+      (restore_focus_frame,
+       Fcons (selected_frame, XFRAME (selected_frame)->focus_frame));
+
 
   /* If the minibuffer is on an iconified or invisible frame,
      make it visible now.  */
diff --git a/src/window.c b/src/window.c
index 792c43d0555..0f114412204 100644
--- a/src/window.c
+++ b/src/window.c
@@ -8006,7 +8006,16 @@ the return value is nil.  Otherwise the value is t.  */)
       if (NILP (data->focus_frame)
 	  || (FRAMEP (data->focus_frame)
 	      && FRAME_LIVE_P (XFRAME (data->focus_frame))))
-	Fredirect_frame_focus (frame, data->focus_frame);
+	{
+	  Lisp_Object frame_focus_frame = f->focus_frame;
+
+	  Fredirect_frame_focus (frame, data->focus_frame);
+
+	  if (EQ (focus_follows_mouse, Qauto_raise)
+	      && NILP (data->focus_frame)
+	      && EQ (selected_frame, frame_focus_frame))
+	    calln (Qselect_frame_set_input_focus, frame, Qnil);
+	}
 
       /* Now, free glyph matrices in windows that were not reused.  */
       for (i = 0; i < n_leaf_windows; i++)
@@ -8094,6 +8103,26 @@ restore_window_configuration (Lisp_Object configuration)
     Fset_window_configuration (configuration, Qnil, Qnil);
 }
 
+void
+restore_focus_frame (Lisp_Object frame_and_focus_frame)
+{
+  Lisp_Object frame = Fcar (frame_and_focus_frame);
+  Lisp_Object focus_frame = Fcdr (frame_and_focus_frame);
+
+  if (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame))
+      && (NILP (focus_frame)
+	  || (FRAMEP (focus_frame) && FRAME_LIVE_P (XFRAME (focus_frame)))))
+    {
+      Lisp_Object frame_focus_frame = XFRAME (frame)->focus_frame;
+
+      Fredirect_frame_focus (frame, focus_frame);
+
+      if (EQ (focus_follows_mouse, Qauto_raise)
+	  && NILP (focus_frame)
+	  && EQ (selected_frame, frame_focus_frame))
+	calln (Qselect_frame_set_input_focus, frame, Qnil);
+    }
+}
 
 /* If WINDOW is an internal window, recursively delete all child windows
    reachable via the next and contents slots of WINDOW.  Otherwise setup
diff --git a/src/window.h b/src/window.h
index 1b4939b40a6..17bb48a3a43 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1125,6 +1125,7 @@ extern Lisp_Object window_from_coordinates (struct frame *, int, int,
                                             enum window_part *, bool, bool, bool);
 extern void resize_frame_windows (struct frame *, int, bool);
 extern void restore_window_configuration (Lisp_Object);
+extern void restore_focus_frame (Lisp_Object);
 extern void delete_all_child_windows (Lisp_Object);
 extern void grow_mini_window (struct window *, int, int);
 extern void shrink_mini_window (struct window *, int);
diff --git a/src/xterm.c b/src/xterm.c
index f3b824c080b..55479eb2c96 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -29094,13 +29094,19 @@ x_focus_frame (struct frame *f, bool noactivate)
 	  && (!dpyinfo->x_focus_frame
 	      || (x_get_toplevel_parent (dpyinfo->x_focus_frame)
 		  != f))
-	  && x_wm_supports (f, dpyinfo->Xatom_net_active_window))
+	  && x_wm_supports (f, dpyinfo->Xatom_net_active_window)
+	  && !EQ (focus_follows_mouse, Qauto_raise))
 	{
 	  /* When window manager activation is possible, use it
 	     instead.  The window manager is expected to perform any
 	     necessary actions such as raising the frame, moving it to
 	     the current workspace, and mapping it, etc, before moving
-	     input focus to the frame.  */
+	     input focus to the frame.
+
+	     Don't use window manager activation when giving focus to a
+	     frame when the mouse would auto-raise it.  At least xfwm
+	     won't give a frame focus via x_ewmh_activate_frame in that
+	     case.  */
 	  x_ewmh_activate_frame (f);
 	  goto out;
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.