aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStéphane Marks2026-02-11 19:01:44 -0500
committerJuri Linkov2026-02-18 19:28:21 +0200
commit54d0764665d899d4a163de30eeafdf62e9afaf3e (patch)
tree34f0a9fef49617db460cff160fe114a1b1088a81 /src
parentf31c61a9aa866fa300726a8e3448bcfdbefb6a64 (diff)
downloademacs-54d0764665d899d4a163de30eeafdf62e9afaf3e.tar.gz
emacs-54d0764665d899d4a163de30eeafdf62e9afaf3e.zip
Add frame-use-time, get-mru-frame, use mru frame in delete-frame (bug#80397)
* lisp/frame.el (get-mru-frame): New defun. * src/frame.c (delete_frame): Call 'get-mru-frame' (when force is not Qnoelisp) to select the most recently used frame that is not the deleted frame as the candidate to select. (syms_of_frame): Qget_mru_frame new DEFSYM. * doc/lispref/frames.texi: Document the new functions. * etc/NEWS: Announce the new functions.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c91
1 files changed, 56 insertions, 35 deletions
diff --git a/src/frame.c b/src/frame.c
index 8dff1470149..6b5d8942db4 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2748,57 +2748,77 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2748 do_switch_frame (mru_rooted_frame (f), 0, 1, Qnil); 2748 do_switch_frame (mru_rooted_frame (f), 0, 1, Qnil);
2749 else 2749 else
2750 { 2750 {
2751 Lisp_Object tail; 2751 frame1 = Qnil;
2752 eassume (CONSP (Vframe_list)); 2752 if (!EQ (force, Qnoelisp))
2753
2754 /* Look for another visible frame on the same terminal.
2755 Do not call next_frame here because it may loop forever.
2756 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
2757 FOR_EACH_FRAME (tail, frame1)
2758 { 2753 {
2759 struct frame *f1 = XFRAME (frame1); 2754 /* Find the most recently used visible frame among all
2760 2755 frames on the same terminal as FRAME, excluding FRAME
2761 if (!EQ (frame, frame1) 2756 which we are about to delete. */
2762 && !FRAME_TOOLTIP_P (f1) 2757 frame1 = calln (Qget_mru_frame, Qvisible, frame);
2763 && FRAME_TERMINAL (f) == FRAME_TERMINAL (f1) 2758 if (!NILP (frame1))
2764 && FRAME_VISIBLE_P (f1)) 2759 {
2765 break; 2760 struct frame *f1 = XFRAME (frame1);
2761 if (FRAME_TOOLTIP_P (f1)
2762 || FRAME_TERMINAL (f) != FRAME_TERMINAL (f1)
2763 || !FRAME_VISIBLE_P (f1))
2764 frame1 = Qnil;
2765 }
2766 } 2766 }
2767 2767
2768 /* If there is none, find *some* other frame. */ 2768 if (NILP (frame1))
2769 if (NILP (frame1) || EQ (frame1, frame))
2770 { 2769 {
2770 Lisp_Object tail;
2771 eassume (CONSP (Vframe_list));
2772
2773 /* Look for another visible frame on the same terminal.
2774 Do not call next_frame here because it may loop forever.
2775 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
2771 FOR_EACH_FRAME (tail, frame1) 2776 FOR_EACH_FRAME (tail, frame1)
2772 { 2777 {
2773 struct frame *f1 = XFRAME (frame1); 2778 struct frame *f1 = XFRAME (frame1);
2774 2779
2775 if (!EQ (frame, frame1) 2780 if (!EQ (frame, frame1)
2776 && FRAME_LIVE_P (f1) 2781 && !FRAME_TOOLTIP_P (f1)
2777 && !FRAME_TOOLTIP_P (f1)) 2782 && FRAME_TERMINAL (f) == FRAME_TERMINAL (f1)
2783 && FRAME_VISIBLE_P (f1))
2784 break;
2785 }
2786
2787 /* If there is none, find *some* other frame. */
2788 if (NILP (frame1) || EQ (frame1, frame))
2789 {
2790 FOR_EACH_FRAME (tail, frame1)
2778 { 2791 {
2779 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1)) 2792 struct frame *f1 = XFRAME (frame1);
2780 {
2781 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
2782 2793
2783 if (!EQ (top_frame, frame)) 2794 if (!EQ (frame, frame1)
2784 frame1 = top_frame; 2795 && FRAME_LIVE_P (f1)
2796 && !FRAME_TOOLTIP_P (f1))
2797 {
2798 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
2799 {
2800 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
2801
2802 if (!EQ (top_frame, frame))
2803 frame1 = top_frame;
2804 }
2805 break;
2785 } 2806 }
2786 break;
2787 } 2807 }
2788 } 2808 }
2789 }
2790#ifdef NS_IMPL_COCOA 2809#ifdef NS_IMPL_COCOA
2791 else 2810 else
2792 { 2811 {
2793 /* Under NS, there is no system mechanism for choosing a new 2812 /* Under NS, there is no system mechanism for choosing a new
2794 window to get focus -- it is left to application code. 2813 window to get focus -- it is left to application code.
2795 So the portion of THIS application interfacing with NS 2814 So the portion of THIS application interfacing with NS
2796 needs to make the frame we switch to the key window. */ 2815 needs to make the frame we switch to the key window. */
2797 struct frame *f1 = XFRAME (frame1); 2816 struct frame *f1 = XFRAME (frame1);
2798 if (FRAME_NS_P (f1)) 2817 if (FRAME_NS_P (f1))
2799 ns_make_frame_key_window (f1); 2818 ns_make_frame_key_window (f1);
2800 } 2819 }
2801#endif 2820#endif
2821 }
2802 2822
2803 do_switch_frame (frame1, 0, 1, Qnil); 2823 do_switch_frame (frame1, 0, 1, Qnil);
2804 sf = SELECTED_FRAME (); 2824 sf = SELECTED_FRAME ();
@@ -7185,6 +7205,7 @@ syms_of_frame (void)
7185 DEFSYM (Qframe_monitor_attributes, "frame-monitor-attributes"); 7205 DEFSYM (Qframe_monitor_attributes, "frame-monitor-attributes");
7186 DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total"); 7206 DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
7187 DEFSYM (Qmake_initial_minibuffer_frame, "make-initial-minibuffer-frame"); 7207 DEFSYM (Qmake_initial_minibuffer_frame, "make-initial-minibuffer-frame");
7208 DEFSYM (Qget_mru_frame, "get-mru-frame");
7188 DEFSYM (Qexplicit_name, "explicit-name"); 7209 DEFSYM (Qexplicit_name, "explicit-name");
7189 DEFSYM (Qheight, "height"); 7210 DEFSYM (Qheight, "height");
7190 DEFSYM (Qicon, "icon"); 7211 DEFSYM (Qicon, "icon");