diff options
| author | Stéphane Marks | 2026-02-11 19:01:44 -0500 |
|---|---|---|
| committer | Juri Linkov | 2026-02-18 19:28:21 +0200 |
| commit | 54d0764665d899d4a163de30eeafdf62e9afaf3e (patch) | |
| tree | 34f0a9fef49617db460cff160fe114a1b1088a81 /src | |
| parent | f31c61a9aa866fa300726a8e3448bcfdbefb6a64 (diff) | |
| download | emacs-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.c | 91 |
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"); |