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; }