mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-11 09:21:23 -07:00
Make 'frame-use-time' more reliable. (bug#80397)
Walking the window tree is more reliable than using the selected window. Implement 'get-mru-frame' on top of 'get-mru-frames' using 'frame-use-time'. * lisp/frame.el (frame-use-time): Change to walk the window tree for the specified frame. (get-mru-frames): New defun. (get-mru-frame): Change to call 'get-mru-frames'. * doc/lispref/frames.texi: Update documentation. * etc/NEWS: Update announcement.
This commit is contained in:
parent
d40e5050be
commit
192d4fc1f7
3 changed files with 105 additions and 60 deletions
|
|
@ -3188,21 +3188,32 @@ could switch to a different terminal without switching back when
|
|||
you're done.
|
||||
@end deffn
|
||||
|
||||
@cindex most recently used frame
|
||||
@defun get-mru-frame &optional all-frames exclude
|
||||
@cindex frame use time
|
||||
@cindex use time of frame
|
||||
@cindex frame order by time of last use
|
||||
@defun frame-use-time &optional frame
|
||||
|
||||
This function is like @code{get-mru-window}, but it returns the most
|
||||
recently used frame. The @dfn{most recently used frame} is the frame
|
||||
with the most recently selected window as computed by
|
||||
@code{get-mru-window}. (@pxref{Selecting Windows})
|
||||
This function returns the use time of frame @var{frame}. @var{frame}
|
||||
must be a live frame and defaults to the selected one.
|
||||
|
||||
This function will return @code{nil} if no candidate frames are found,
|
||||
for example, if there is only one frame. Tooltip, minibuffer only, and
|
||||
child frames are never candidates.
|
||||
The @dfn{use time of a frame} is the highest use time as reported by
|
||||
@code{window-use-time} of any window on @var{frame}.
|
||||
@end defun
|
||||
|
||||
Since in practice the most recently used frame is always the selected
|
||||
one, it usually makes sense to call this function with a non-@code{nil}
|
||||
@var{exclude} argument with, for example, the selected frame.
|
||||
@defun get-mru-frame &optional all-frames exclude-child-frames exclude-frame
|
||||
|
||||
This function returns the frame with the highest use time as reported by
|
||||
@code{frame-use-time}. It returns @code{nil} if no candidate frames are
|
||||
found which usually happens if frames are excluded with the help of the
|
||||
optional arguments.
|
||||
|
||||
By default, tooltip and minibuffer-only frames are never candidates. If
|
||||
the optional argument @var{exclude-child-frames} is non-nil, child
|
||||
frames are excluded too. The @var{exclude-frame} argument, if present,
|
||||
excludes the frame it specifies too. Since in practice the most
|
||||
recently used frame is always the selected one, it usually makes sense
|
||||
to call this function with a non-@code{nil} @var{exclude-frame} argument
|
||||
specifying the selected frame.
|
||||
|
||||
The optional argument @var{all-frames} specifies which frames to
|
||||
consider:
|
||||
|
|
@ -3210,31 +3221,47 @@ consider:
|
|||
@itemize @bullet
|
||||
@item @code{visible}
|
||||
means to consider all visible frames on the current terminal or
|
||||
@var{exclude}'s terminal.
|
||||
@var{exclude-frame}'s terminal.
|
||||
|
||||
@item 0
|
||||
means to consider all visible or iconified frames on the current
|
||||
terminal or @var{exclude}'s terminal.
|
||||
terminal or @var{exclude-frame}'s terminal.
|
||||
|
||||
@item Anything else
|
||||
means to consider all frames.
|
||||
@end itemize
|
||||
|
||||
If @code{get-mru-frame} is called from within the body of
|
||||
@code{with-selected-frame}, it may yield unexpected results as the most
|
||||
recently used window will not necessarily match the selected one in the
|
||||
temporarily selected frame. (@pxref{Selecting Windows})
|
||||
@end defun
|
||||
|
||||
@cindex frame use time
|
||||
@cindex use time of frame
|
||||
@cindex frame order by time of last use
|
||||
@defun frame-use-time &optional frame
|
||||
@defun get-mru-frames &optional all-frames exclude-child-frames exclude-frame
|
||||
|
||||
This function returns the use time of frame @var{frame}. @var{frame}
|
||||
must be a live frame and defaults to the selected one. The result is
|
||||
the @code{window-use-time} of @var{frame}'s most recently used window
|
||||
computed by @code{get-mru-window}. (@pxref{Selecting Windows})
|
||||
This function returns a list of frames sorted by highest use time as
|
||||
reported by @code{frame-use-time} which is computed using each frame's
|
||||
most recently used window.
|
||||
|
||||
By default, tooltip and minibuffer-only frames are never candidates. If
|
||||
the optional argument @var{exclude-child-frames} is non-nil, child
|
||||
frames are excluded too. The @var{exclude-frame} argument, if present,
|
||||
excludes the frame it specifies too.
|
||||
|
||||
It can return @code{nil} which can happen if frames are excluded with
|
||||
the help of the optional arguments, for example, if there is a single
|
||||
frame and @var{exclude-frame} is the selected frame.
|
||||
|
||||
The optional argument @var{all-frames} specifies which frames to
|
||||
consider:
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{visible}
|
||||
means to consider all visible frames on the current terminal or
|
||||
@var{exclude-frame}'s terminal.
|
||||
|
||||
@item 0
|
||||
means to consider all visible or iconified frames on the current
|
||||
terminal or @var{exclude-frame}'s terminal.
|
||||
|
||||
@item Anything else
|
||||
means to consider all frames.
|
||||
@end itemize
|
||||
@end defun
|
||||
|
||||
@deffn Command select-frame-by-id id &optional noerror
|
||||
|
|
|
|||
12
etc/NEWS
12
etc/NEWS
|
|
@ -507,12 +507,12 @@ for a window. The result is the `window-use-time' of a frame's most
|
|||
recently used window.
|
||||
|
||||
+++
|
||||
*** New function 'get-mru-frame'.
|
||||
This function returns the most recently used frame from among all
|
||||
frames, or those visible or iconified on the same terminal as the
|
||||
selected frame. A frame can be excluded, for example, the selected
|
||||
frame, as it will always be the most recently used frame on the current
|
||||
terminal.
|
||||
*** New functions 'get-mru-frames' and 'get-mru-frame'.
|
||||
'get-mru-frames' returns a list of frames sorted by their most recent
|
||||
use time from among all frames, or those visible or iconified on the
|
||||
same terminal as the selected frame. Child frames can be excluded. A
|
||||
single frame can be excluded, for example, the selected frame.
|
||||
'get-mru-frame' returns the single most recently used frame.
|
||||
|
||||
---
|
||||
*** After deleting, 'delete-frame' now selects the most recently used frame.
|
||||
|
|
|
|||
|
|
@ -2615,41 +2615,43 @@ for FRAME."
|
|||
|
||||
(defun frame-use-time (&optional frame)
|
||||
"Return FRAME's last use time.
|
||||
The result is the `window-use-time' of FRAME's most recently used window
|
||||
computed by `get-mru-window'. If optional FRAME is nil, use the
|
||||
selected frame."
|
||||
(window-use-time
|
||||
;; Arguments to `get-mru-window' consider all windows.
|
||||
(get-mru-window (window-normalize-frame frame) t t t)))
|
||||
The result is the highest `window-use-time' of any window on FRAME. If
|
||||
optional FRAME is nil, use the selected frame."
|
||||
(let ((time 0))
|
||||
(walk-window-tree
|
||||
(lambda (window)
|
||||
(setq time (max time (window-use-time window))))
|
||||
frame)
|
||||
time))
|
||||
|
||||
(defun get-mru-frame (&optional all-frames exclude)
|
||||
"Return the most recently used frame on frames specified by ALL-FRAMES.
|
||||
Compute the result from each frame's most recently used window computed
|
||||
by `get-mru-window', which see. Return nil if no candidate frames are
|
||||
found, for example, if there is only one frame. Tooltip, minibuffer
|
||||
only, and child frames are never candidates. Optional argument EXCLUDE,
|
||||
when non-nil, is a frame to exclude, for example, the selected frame.
|
||||
(defun get-mru-frames (&optional all-frames
|
||||
exclude-child-frames
|
||||
exclude-frame)
|
||||
"Return a frame list sorted by most recent use and filtered by ALL-FRAMES.
|
||||
Compute the result using `frame-use-time', which see. Tooltip, and
|
||||
minibuffer only frames are never candidates. If optional argument
|
||||
EXCLUDE-CHILD-FRAMES is non-nil, eliminate child frames as candidates.
|
||||
If EXCLUDE-FRAME is non-nil, it is a frame to exclude, for example, the
|
||||
selected frame.
|
||||
|
||||
The following non-nil values of the optional argument ALL-FRAMES
|
||||
have special meanings:
|
||||
|
||||
- `visible' means consider all visible frames on the current terminal
|
||||
or EXCLUDE's terminal if non-nil.
|
||||
or EXCLUDE-FRAME's terminal if EXCLUDE-FRAME is non-nil.
|
||||
|
||||
- 0 (the number zero) means consider all all visible and iconified
|
||||
frames on the current terminal or EXCLUDE's terminal if non-nil.
|
||||
frames on the current terminal or EXCLUDE-FRAME's terminal if
|
||||
EXCLUDE-FRAME is non-nil.
|
||||
|
||||
Any other value of ALL-FRAMES means consider all frames."
|
||||
(setq all-frames (or all-frames t))
|
||||
(let* ((mru-frame)
|
||||
(time)
|
||||
(best-time 0)
|
||||
(terminal (frame-terminal (or exclude (selected-frame))))
|
||||
(let* ((terminal (frame-terminal (or exclude-frame (selected-frame))))
|
||||
(frame-list
|
||||
(seq-remove (lambda (frame)
|
||||
(or (eq frame exclude)
|
||||
(or (eq frame exclude-frame)
|
||||
(eq (frame-parameter frame 'minibuffer) 'only)
|
||||
(frame-parent frame)))
|
||||
(and exclude-child-frames (frame-parent frame))))
|
||||
(cond
|
||||
((eq all-frames 'visible)
|
||||
(seq-filter (lambda (frame)
|
||||
|
|
@ -2660,12 +2662,28 @@ Any other value of ALL-FRAMES means consider all frames."
|
|||
(eq (frame-terminal frame) terminal))
|
||||
(frame-list)))
|
||||
(t (frame-list))))))
|
||||
(dolist (frame frame-list)
|
||||
(setq time (frame-use-time frame))
|
||||
(when (> time best-time)
|
||||
(setq best-time time)
|
||||
(setq mru-frame frame)))
|
||||
mru-frame))
|
||||
(sort frame-list :key #'frame-use-time :reverse t)))
|
||||
|
||||
(defun get-mru-frame (&optional all-frames exclude-child-frames exclude-frame)
|
||||
"Return the most recently used frame on frames specified by ALL-FRAMES.
|
||||
Compute the result using `frame-use-time', which see. Tooltip, and
|
||||
minibuffer only frames are never candidates. If optional argument
|
||||
EXCLUDE-CHILD-FRAMES is non-nil, eliminate child frames as candidates.
|
||||
If EXCLUDE-FRAME is non-nil, it is a frame to exclude, for example, the
|
||||
selected frame.
|
||||
|
||||
The following non-nil values of the optional argument ALL-FRAMES
|
||||
have special meanings:
|
||||
|
||||
- `visible' means consider all visible frames on the current terminal
|
||||
or EXCLUDE-FRAME's terminal if EXCLUDE-FRAME is non-nil.
|
||||
|
||||
- 0 (the number zero) means consider all all visible and iconified
|
||||
frames on the current terminal or EXCLUDE-FRAME's terminal if
|
||||
EXCLUDE-FRAME is non-nil.
|
||||
|
||||
Any other value of ALL-FRAMES means consider all frames."
|
||||
(car (get-mru-frames all-frames exclude-child-frames exclude-frame)))
|
||||
|
||||
;;;; Frame/display capabilities.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue