]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix and document frame parameters for text terminals and child frames
authorMartin Rudalics <rudalics@gmx.at>
Sat, 22 Mar 2025 08:34:53 +0000 (09:34 +0100)
committerEshel Yaron <me@eshelyaron.com>
Sun, 23 Mar 2025 19:23:57 +0000 (20:23 +0100)
* src/frame.c (Fmake_frame_invisible): In doc-string describe
effect on text terminals.  Set FRAME correctly when called with
nil value.  Make frame invisible before calling mru_rooted_frame
or next_frame.
(Ficonify_frame): Make it work for child frames on text
terminals
(Fmodify_frame_parameters): Make value 'icon' for 'visibility'
work for child frames.
* src/dispnew.c (frame_ancestors_visible_p): New function.
(frames_with_root): If VISIBLE_ONLY is non-nil, return only
frames whose ancestors are all visible to avoid that redisplay
draws visibly orphaned child frames.
* doc/lispref/frames.texi (Frames): Move descriptions of top
frame and 'tty-top-frame' here.
(Frame Layout): Mention that on text terminals the outer border
can be emulated by setting the 'undecorated' frame parameter.
(Frame Position, Frame Parameters, Window Frame Parameters)
(Position Parameters, Size Parameters): Rewrite sections dealing
with the handling of frame parameters in text terminals.
(Layout Parameters): Move description of 'undecorated' parameter
here.  Clarify semantics of 'menu-bar-lines' parameter.
(Frame Interaction Parameters): Move description of 'visibility'
parameter here.  Mention which parameters are not implemented on
text terminals.
(Mouse Dragging Parameters): Describe how these work on text
terminals.
(Visibility of Frames): Rewrite section.
(Raising and Lowering): Describe for text terminals.
(Child Frames): Fix description of 'iconify-child-frame' option.

(cherry picked from commit 1ee2a921ad528e18cc68c594f4f2ffcb0599cfe7)

doc/lispref/frames.texi
src/dispnew.c
src/frame.c

index 8c843952c2967c24ba3a58abdb6f095a5463663a..7eacb790ce7e294741febd6f9075cee5f102d915 100644 (file)
@@ -26,22 +26,28 @@ object that represents a terminal.  @xref{Terminal Type}.
 @cindex text terminal
 @cindex graphical terminal
 @cindex graphical display
+@cindex top frame
   There are two classes of terminals: @dfn{text terminals} and
 @dfn{graphical terminals}.  Text terminals are non-graphics-capable
-displays, including @command{xterm} and other terminal emulators.  On
-a text terminal, each Emacs frame occupies the terminal's entire
-screen; although you can create additional frames and switch between
-them, the terminal only shows one frame at a time.  Graphical
-terminals, on the other hand, are managed by graphical display systems
-such as the X Window System, which allow Emacs to show multiple frames
-simultaneously on the same display.
+displays, including @command{xterm} and other terminal emulators.  On a
+text terminal, each Emacs frame occupies the terminal's entire screen;
+although you can create additional frames and switch between them, the
+terminal only shows one non-child frame at a time.  This frame is
+referred to as the @dfn{top frame} of that terminal and can be retrieved
+with the function @code{tty-top-frame} described below.  A top frame may
+have child frames (@pxref{Child Frames}) which will be shown together
+with it but cannot be a child frame itself.
+
+Graphical terminals, on the other hand, are managed by graphical display
+systems such as the X Window System, which allow Emacs to show multiple
+frames simultaneously on the same display.
 
   On GNU and Unix systems, you can create additional frames on any
-available terminal, within a single Emacs session, regardless of
-whether Emacs was started on a text or graphical terminal.  Emacs can
-display on both graphical and text terminals simultaneously.  This
-comes in handy, for instance, when you connect to the same session
-from several remote locations.  @xref{Multiple Terminals}.
+available terminal, within a single Emacs session, regardless of whether
+Emacs was started on a text or graphical terminal.  Emacs can display on
+both, graphical and text terminals, simultaneously.  This comes in
+handy, for instance, when you connect to the same session from several
+remote locations.  @xref{Multiple Terminals}.
 
 @defun framep object
 This predicate returns a non-@code{nil} value if @var{object} is a
@@ -70,9 +76,9 @@ The frame is displayed on an Android device.
 @end defun
 
 @defun frame-terminal &optional frame
-This function returns the terminal object that displays @var{frame}.
-If @var{frame} is @code{nil} or unspecified, it defaults to the
-selected frame.
+This function returns the terminal object that displays @var{frame}.  If
+@var{frame} is @code{nil} or unspecified, it defaults to the selected
+frame (@pxref{Input Focus}).
 @end defun
 
 @defun terminal-live-p object
@@ -90,6 +96,19 @@ of the window-system's root window for that terminal.  A child frame is
 a frame whose window-system window is the child of the window-system
 window of another Emacs frame.  @xref{Child Frames}.
 
+On a text terminal you can get its top frame with the following
+function:
+
+@defun tty-top-frame &optional terminal
+This function returns the top frame on @var{terminal}.  @var{terminal}
+should be a terminal object, a frame (meaning that frame's terminal), or
+@code{nil} (meaning the selected frame's terminal).  If it does not
+refer to a text terminal, the return value is @code{nil}.  A top frame
+must be a root frame, which means it cannot be a child frame itself
+(@pxref{Child Frames}), but may have an arbitrary number of child frames
+descending from it.
+@end defun
+
 @menu
 * Creating Frames::             Creating additional frames.
 * Multiple Terminals::          Displaying on several different devices.
@@ -595,8 +614,8 @@ normal, top-level frame these parameters usually represent its absolute
 position (see below) with respect to its display's origin.  For a child
 frame (@pxref{Child Frames}) these parameters represent its position
 relative to the native position (see below) of its parent frame.  For
-frames on text terminals the values of these parameters are meaningless
-and always zero.
+root frames (@pxref{Child Frames}) on text terminals the values of these
+parameters are meaningless and always zero.
 
 @item External Border
 @cindex external border
@@ -622,11 +641,14 @@ by the window manager like tooltip frames (@pxref{Tooltips}), child
 frames (@pxref{Child Frames}) and @code{undecorated} or
 @code{override-redirect} frames (@pxref{Management Parameters}).
 
-Outer borders are never shown on text terminal frames and on frames
-generated by GTK+ routines.  On MS-Windows, the outer border is emulated
-with the help of a one pixel wide external border.  Non-toolkit builds
-on X allow changing the color of the outer border by setting the
-@code{border-color} frame parameter (@pxref{Layout Parameters}).
+As a rule, outer borders are never shown on text terminal frames and on
+frames generated by GTK+ routines.  For a child frame on a text terminal
+you can emulate the outer border by setting the @code{undecorated}
+parameter of that frame to @code{nil} (@pxref{Layout Parameters}).  On
+MS-Windows, the outer border is emulated with the help of a one pixel
+wide external border.  Non-toolkit builds on X allow changing the color
+of the outer border by setting the @code{border-color} frame parameter
+(@pxref{Layout Parameters}).
 
 @item Title Bar
 @cindex title bar
@@ -1003,7 +1025,8 @@ invisible).  However, on systems where the display's origin does not
 coincide with its top-left corner, the frame may be visible on a
 secondary monitor.
 
-On a text terminal frame both values are zero.
+On a text terminal frame both values are zero for root frames
+(@pxref{Child Frames}).
 @end defun
 
 @defun set-frame-position frame x y
@@ -1325,18 +1348,10 @@ unaffected by the setting of this option.
 @cindex frame parameters
 
   A frame has many parameters that control its appearance and behavior.
-Just what parameters a frame has depends on what display mechanism it
-uses.
-
-  Frame parameters exist mostly for the sake of graphical displays.
-Most frame parameters have no effect when applied to a frame on a text
-terminal; only the @code{height}, @code{width}, @code{name},
-@code{title}, @code{menu-bar-lines}, @code{buffer-list} and
-@code{buffer-predicate} parameters do something special.  If the
-terminal supports colors, the parameters @code{foreground-color},
-@code{background-color}, @code{background-mode} and
-@code{display-type} are also meaningful.  If the terminal supports
-frame transparency, the parameter @code{alpha} is also meaningful.
+Just what parameters are meaningful for a frame depends on what display
+mechanism it uses.  Many frame parameters exist mostly for the sake of
+graphical displays and have no effect when applied to the top frame
+(@pxref{Frames}) of a text terminal.
 
   By default, frame parameters are saved and restored by the desktop
 library functions (@pxref{Desktop Save Mode}) when the variable
@@ -1490,11 +1505,7 @@ Arguments for Emacs Invocation, emacs, The GNU Emacs Manual}.
 
   Just what parameters a frame has depends on what display mechanism
 it uses.  This section describes the parameters that have special
-meanings on some or all kinds of terminals.  Of these, @code{name},
-@code{title}, @code{height}, @code{width}, @code{buffer-list} and
-@code{buffer-predicate} provide meaningful information in terminal
-frames, and @code{tty-color-mode} is meaningful only for frames on
-text terminals.
+meanings on some or all kinds of terminals.
 
 @menu
 * Basic Parameters::            Parameters that are fundamental.
@@ -1575,8 +1586,8 @@ measured in pixels.  For a normal, non-child frame they specify the
 frame's outer position (@pxref{Frame Geometry}) relative to its
 display's origin.  For a child frame (@pxref{Child Frames}) they specify
 the frame's outer position relative to the native position of the
-frame's parent frame.  (Note that none of these parameters is meaningful
-on TTY frames.)
+frame's parent frame.  On a text terminal these parameters are
+meaningful for child frames only.
 
 @table @code
 @vindex left@r{, a frame parameter}
@@ -1628,6 +1639,8 @@ unavailable before a frame has been made visible, it is generally not
 advisable to use floating-point values when creating decorated frames.
 Floating-point values are more suited for ensuring that an (undecorated)
 child frame is positioned nicely within the area of its parent frame.
+
+Floating-point values are currently not handled on text terminal frames.
 @end table
 
 Some window managers ignore program-specified positions.  If you want to
@@ -1664,15 +1677,17 @@ just like @code{left}, except vertically instead of horizontally.
 @item icon-left
 The screen position of the left edge of the frame's icon, in pixels,
 counting from the left edge of the screen.  This takes effect when the
-frame is iconified, if the window manager supports this feature.  If
-you specify a value for this parameter, then you must also specify a
-value for @code{icon-top} and vice versa.
+frame is iconified, if the window manager supports this feature.  If you
+specify a value for this parameter, then you must also specify a value
+for @code{icon-top} and vice versa.  This parameter has no meaning on a
+text terminal.
 
 @vindex icon-top@r{, a frame parameter}
 @item icon-top
 The screen position of the top edge of the frame's icon, in pixels,
 counting from the top edge of the screen.  This takes effect when the
-frame is iconified, if the window manager supports this feature.
+frame is iconified, if the window manager supports this feature.  This
+parameter has no meaning on a text terminal.
 
 @vindex user-position@r{, a frame parameter}
 @item user-position
@@ -1680,7 +1695,8 @@ When you create a frame and specify its screen position with the
 @code{left} and @code{top} parameters, use this parameter to say whether
 the specified position was user-specified (explicitly requested in some
 way by a human user) or merely program-specified (chosen by a program).
-A non-@code{nil} value says the position was user-specified.
+A non-@code{nil} value says the position was user-specified.  This
+parameter has no meaning on a text terminal.
 
 @cindex window positions and window managers
 Window managers generally heed user-specified positions, and some heed
@@ -1699,6 +1715,7 @@ parameters represent the user's stated preference; otherwise, use
 @item z-group
 This parameter specifies a relative position of the frame's
 window-system window in the stacking (Z-) order of the frame's display.
+It has not been implemented yet on text terminals.
 
 If this is @code{above}, the window-system will display the window
 that corresponds to the frame above all other window-system windows
@@ -1720,7 +1737,8 @@ function @code{frame-restack} (@pxref{Raising and Lowering}).
 
 Frame parameters usually specify frame sizes in character units.  On
 graphical displays, the @code{default} face determines the actual pixel
-sizes of these character units (@pxref{Face Attributes}).
+sizes of these character units (@pxref{Face Attributes}).  On text
+terminals size parameters affect child frames only.
 
 @table @code
 @vindex width@r{, a frame parameter}
@@ -1779,7 +1797,7 @@ This parameter specifies the height of the frame.  It works just like
 This does for the size parameters @code{height} and @code{width} what
 the @code{user-position} parameter (@pxref{Position Parameters,
 user-position}) does for the position parameters @code{top} and
-@code{left}.
+@code{left}.  This parameter has no meaning on a text terminal.
 
 @vindex min-width@r{, a frame parameter}
 @item min-width
@@ -1810,17 +1828,18 @@ fit will be clipped by the window manager.
 @vindex fullscreen@r{, a frame parameter}
 @item fullscreen
 This parameter specifies whether to maximize the frame's width, height
-or both.  Its value can be @code{fullwidth}, @code{fullheight},
-@code{fullboth}, or @code{maximized}.@footnote{On PGTK frames, setting
-the values @code{fullheight} and @code{fullwidth} has no effect.}  A
+or both.  It has no meaning on a text terminal.  Its value can be
+@code{fullwidth}, @code{fullheight}, @code{fullboth}, or
+@code{maximized}.@footnote{On PGTK frames, setting the values
+@code{fullheight} and @code{fullwidth} has no effect.}  A
 @dfn{fullwidth} frame is as wide as possible, a @dfn{fullheight} frame
 is as tall as possible, and a @dfn{fullboth} frame is both as wide and
 as tall as possible.  A @dfn{maximized} frame is like a ``fullboth''
 frame, except that it usually keeps its title bar and the buttons for
-resizing and closing the frame.  Also, maximized frames typically
-avoid hiding any task bar or panels displayed on the desktop.  A
-``fullboth'' frame, on the other hand, usually omits the title bar and
-occupies the entire available screen space.
+resizing and closing the frame.  Also, maximized frames typically avoid
+hiding any task bar or panels displayed on the desktop.  A ``fullboth''
+frame, on the other hand, usually omits the title bar and occupies the
+entire available screen space.
 
 Full-height and full-width frames are more similar to maximized
 frames in this regard.  However, these typically display an external
@@ -1856,7 +1875,7 @@ file as, for example
 @end example
 
 This will give a new frame full height after typing in it @key{F11} for
-the first time.
+the first time.  This parameter has no meaning on a text terminal.
 
 @vindex fit-frame-to-buffer-margins@r{, a frame parameter}
 @item fit-frame-to-buffer-margins
@@ -1879,10 +1898,31 @@ Windows}).
 @cindex layout parameters of frames
 @cindex frame layout parameters
 
-  These frame parameters enable or disable various parts of the
-frame, or control their sizes.
+  These frame parameters enable or disable various parts of the frame,
+or control their sizes.  Unless stated otherwise, these parameters have
+no meaning on text terminals.
 
 @table @code
+@vindex undecorated@r{, a frame parameter}
+@item undecorated
+If non-@code{nil}, then on a graphical system this frame's window-system
+window is drawn without decorations, like the title, minimize/maximize
+boxes and external borders.  This usually means that the window cannot
+be dragged, resized, iconified, maximized or deleted with the mouse.  If
+@code{nil}, the frame's window is usually drawn with all the elements
+listed above unless their display has been suspended via window manager
+settings.
+
+Under X, Emacs uses the Motif window manager hints to turn off
+decorations.  Some window managers may not honor these hints.
+
+NS builds consider the tool bar to be a decoration, and therefore hide
+it on an undecorated frame.
+
+On a text terminal, this parameter, if non-@code{nil}, will make a child
+frame show an outer border, which allows to resize that frame via mouse
+dragging (@pxref{Mouse Dragging Parameters}).
+
 @vindex border-width@r{, a frame parameter}
 @item border-width
 The width in pixels of the frame's outer border (@pxref{Frame Geometry}).
@@ -1948,13 +1988,15 @@ to not draw bottom dividers.
 @vindex menu-bar-lines@r{, a frame parameter}
 @item menu-bar-lines
 The number of lines to allocate at the top of the frame for a menu bar
-(@pxref{Menu Bar}).  The default is one if Menu Bar mode is enabled
-and zero otherwise.  @xref{Menu Bars,,,emacs, The GNU Emacs Manual}.
-For an external menu bar (@pxref{Frame Layout}), this value remains
-unchanged even when the menu bar wraps to two or more lines.  In that
-case, the @code{menu-bar-size} value returned by @code{frame-geometry}
-(@pxref{Frame Geometry}) enables you to establish whether the menu bar
-actually occupies one or more lines.
+(@pxref{Menu Bar}).  The default is 1 if Menu Bar mode is enabled and 0
+otherwise.  @xref{Menu Bars,,,emacs, The GNU Emacs Manual}.  For an
+external menu bar (@pxref{Frame Layout}), this value remains unchanged
+even when the menu bar wraps to two or more lines.  In that case, the
+@code{menu-bar-size} value returned by @code{frame-geometry}
+(@pxref{Frame Geometry}) can be used to establish whether the menu bar
+actually occupies one or more lines.  This parameter affects the
+presence of a menu bar on the root frame (@pxref{Child Frames}) of a
+text terminal too.  On a text terminal the value may be only 0 or 1.
 
 @vindex tool-bar-lines@r{, a frame parameter}
 @item tool-bar-lines
@@ -1976,7 +2018,8 @@ than Nextstep, and @code{left} or @code{right} on builds using GTK+.
 The number of lines to use for the tab bar (@pxref{Tab Bars,,,emacs, The
 GNU Emacs Manual}).  The default is one if Tab Bar mode is enabled and
 zero otherwise.  This value may change whenever the tab bar wraps
-(@pxref{Frame Layout}).
+(@pxref{Frame Layout}).  This parameter affects the presence of a tab
+bar on the root frame (@pxref{Child Frames}) of a text terminal too.
 
 @vindex line-spacing@r{, a frame parameter}
 @item line-spacing
@@ -1991,11 +2034,11 @@ displayed by this frame.  This is useful to eliminate such glyphs when
 fitting a frame to its buffer via @code{fit-frame-to-buffer}
 (@pxref{Resizing Windows}).  This frame parameter has effect only for
 GUI frames shown on graphical displays, and only if the fringes are
-disabled.  This parameter is intended as a purely-presentation
-feature, and in particular should not be used for frames where the
-user can interactively insert text, or more generally where the cursor
-is shown.  A notable example of frames where this is used is tooltip
-frames (@pxref{Tooltips}).
+disabled.  This parameter is intended as a purely-presentation feature,
+and in particular should not be used for frames where the user can
+interactively insert text, or more generally where the cursor is shown.
+A notable example of frames where this is used is tooltip frames
+(@pxref{Tooltips}).  This parameter affects text terminals as well.
 @end table
 
 
@@ -2058,6 +2101,12 @@ If non-@code{nil}, this frame's window is never split automatically.
 These parameters supply forms of interactions between different frames.
 
 @table @code
+@vindex visibility@r{, a frame parameter}
+@item visibility
+The state of visibility of the frame.  There are three possibilities:
+@code{nil} for invisible, @code{t} for visible, and @code{icon} for
+iconified.  @xref{Visibility of Frames}.
+
 @vindex parent-frame@r{, a frame parameter}
 @item parent-frame
 If non-@code{nil}, this means that this frame is a child frame
@@ -2075,7 +2124,7 @@ Frames}.
 If non-@code{nil}, this parameter specifies the frame whose windows will
 be scrolled whenever the mouse wheel is scrolled with the mouse pointer
 hovering over this frame, see @ref{Mouse Commands,,, emacs, The GNU
-Emacs Manual}.
+Emacs Manual}.  This parameter has no meaning on a text terminal.
 
 @vindex no-other-frame@r{, a frame parameter}
 @item no-other-frame
@@ -2089,7 +2138,8 @@ Commands,,, emacs, The GNU Emacs Manual}.
 When this parameter specifies a function, that function will be called
 instead of the function specified by the variable
 @code{frame-auto-hide-function} when quitting the frame's only window
-(@pxref{Quitting Windows}) and there are other frames left.
+(@pxref{Quitting Windows}) and there are other frames left.  This
+parameter has not been yet implemented on text terminals.
 
 @vindex minibuffer-exit@r{, a frame parameter}
 @item minibuffer-exit
@@ -2098,7 +2148,8 @@ frame invisible whenever the minibuffer (@pxref{Minibuffers}) is exited.
 Alternatively, it can specify the functions @code{iconify-frame} and
 @code{delete-frame}.  This parameter is useful to make a child frame
 disappear automatically (similar to how Emacs deals with a window) when
-exiting the minibuffer.
+exiting the minibuffer.  This parameter has not been yet implemented on
+text terminals.
 
 @vindex keep-ratio@r{, a frame parameter}
 @item keep-ratio
@@ -2120,7 +2171,8 @@ either @code{t} or @code{width-only}.  The height ratio is preserved if
 the @sc{car} of the cell is either @code{t} or @code{height-only}.  The
 left position ratio is preserved if the @sc{cdr} of the cell is either
 @code{t} or @code{left-only}.  The top position ratio is preserved if
-the @sc{cdr} of the cell is either @code{t} or @code{top-only}.
+the @sc{cdr} of the cell is either @code{t} or @code{top-only}.  This
+parameter has not been yet implemented on text terminals.
 @end table
 
 
@@ -2137,13 +2189,15 @@ or the mode line of its bottommost window.
 
 These parameters are mostly useful for child frames (@pxref{Child
 Frames}) that come without window manager decorations.  If necessary,
-they can be used for undecorated top-level frames as well.
+they can be used for undecorated top-level frames as well.  On text
+terminals these parameters affect child frames only.
 
 @table @code
 @vindex drag-internal-border@r{, a frame parameter}
 @item drag-internal-border
 If non-@code{nil}, the frame can be resized by dragging its internal
-borders, if present, with the mouse.
+borders, if present, with the mouse.  On text terminals, the decoration
+of a child frame must be dragged instead.
 
 @vindex drag-with-header-line@r{, a frame parameter}
 @item drag-with-header-line
@@ -2200,12 +2254,6 @@ interaction with the window manager or window system.  They have no
 effect on text terminals.
 
 @table @code
-@vindex visibility@r{, a frame parameter}
-@item visibility
-The state of visibility of the frame.  There are three possibilities:
-@code{nil} for invisible, @code{t} for visible, and @code{icon} for
-iconified.  @xref{Visibility of Frames}.
-
 @vindex auto-raise@r{, a frame parameter}
 @item auto-raise
 If non-@code{nil}, Emacs automatically raises the frame when it is
@@ -2304,21 +2352,6 @@ will not be able to receive any keyboard input from the user, not even
 if the user switches to the frame using the key combination
 @kbd{Alt-@key{TAB}}.
 
-@vindex undecorated@r{, a frame parameter}
-@item undecorated
-If non-@code{nil}, this frame's window-system window is drawn without
-decorations, like the title, minimize/maximize boxes and external
-borders.  This usually means that the window cannot be dragged, resized,
-iconified, maximized or deleted with the mouse.  If @code{nil}, the frame's
-window is usually drawn with all the elements listed above unless their
-display has been suspended via window manager settings.
-
-Under X, Emacs uses the Motif window manager hints to turn off
-decorations.  Some window managers may not honor these hints.
-
-NS builds consider the tool bar to be a decoration, and therefore hide
-it on an undecorated frame.
-
 @vindex override-redirect@r{, a frame parameter}
 @item override-redirect
 @cindex override redirect frames
@@ -3240,33 +3273,49 @@ window managers refer to this state as @dfn{minimized} rather than
 @dfn{iconified}, but from Emacs's point of view they are the same thing).
 If a frame is invisible, it is not displayed at all.
 
+On a text terminal a frame may be only visible or invisible.  The top
+frame (@pxref{Frames}) of a terminal cannot be invisible.
+
 @cindex mapped frame
 @cindex unmapped frame
-  The concept of visibility is strongly related to that of (un-)mapped
-frames.  A frame (or, more precisely, its window-system window) is and
-becomes @dfn{mapped} when it is displayed for the first time and
-whenever it changes its state of visibility from @code{iconified} or
-@code{invisible} to @code{visible}.  Conversely, a frame is and becomes
-@dfn{unmapped} whenever it changes its status from @code{visible} to
-@code{iconified} or @code{invisible}.
-
-  Visibility is meaningless on text terminals, since only the selected
-frame is actually displayed in any case.
+  On graphical displays the concept of visibility is strongly related to
+that of (un-)mapped frames.  A frame (or, more precisely, its
+window-system window) is and becomes @dfn{mapped} when it is displayed
+for the first time and whenever it changes its state of visibility from
+@code{iconified} or @code{invisible} to @code{visible}.  Conversely, a
+frame is and becomes @dfn{unmapped} whenever it changes its status from
+@code{visible} to @code{iconified} or @code{invisible}.
 
 @defun frame-visible-p frame
 This function returns the visibility status of frame @var{frame}.  The
 value is @code{t} if @var{frame} is visible, @code{nil} if it is
 invisible, and @code{icon} if it is iconified.
 
-On a text terminal, all frames are considered visible for the
-purposes of this function, even though only one frame is displayed.
-@xref{Raising and Lowering}.
+Note that the visibility status of a frame as reported by this function
+(and by the @code{visibility} frame parameter, @ref{Frame Interaction
+Parameters}) does not necessarily tell whether the frame is actually
+seen on display.  Any such frame can be partially or completely obscured
+by other window manager windows on the same graphical terminal.  Whether
+that completely hides the frame may then depend on the transparency of
+the obscuring window.  A frame may also reside on a virtual desktop
+different from the current one and can be seen only when making that
+desktop the current one.  One notable restriction holds for child frames
+(@pxref{Child Frames}): A child frame can be seen if and only if this
+function returns true for all its ancestors including the frame itself
+and its root frame.
+
+  On a text terminal only that terminal's top frame and its child frames
+can be actually seen.  Other root frames and their child frames cannot
+be seen even if they are considered visible by this function.
 @end defun
 
 @deffn Command iconify-frame &optional frame
 This function iconifies frame @var{frame}.  If you omit @var{frame}, it
-iconifies the selected frame.  This usually makes all child frames of
-@var{frame} (and their descendants) invisible (@pxref{Child Frames}).
+iconifies the selected frame.  This will also remove any child frames
+(@pxref{Child Frames}) of @var{frame} from display.  On the top frame of
+a text terminal this function has no effect.  visible. If @var{frame} is
+a child frame, the behavior depends on the value of the variable
+@code{iconify-child-frame} (@pxref{Child Frames}).
 @end deffn
 
 @deffn Command make-frame-visible &optional frame
@@ -3275,8 +3324,8 @@ it makes the selected frame visible.  This does not raise the frame, but
 you can do that with @code{raise-frame} if you wish (@pxref{Raising and
 Lowering}).
 
-Making a frame visible usually makes all its child frames (and their
-descendants) visible as well (@pxref{Child Frames}).
+Making a frame visible makes all its child frames with visible ancestors
+appear on display again (@pxref{Child Frames}).
 @end deffn
 
 @deffn Command make-frame-invisible &optional frame force
@@ -3286,11 +3335,19 @@ all child frames of @var{frame} (and their descendants) invisible too
 (@pxref{Child Frames}).
 
 Unless @var{force} is non-@code{nil}, this function refuses to make
-@var{frame} invisible if all other frames are invisible.
+@var{frame} invisible if all other frames are invisible.  On a text
+terminal this will make @var{frame} invisible if and only if it is a
+child frame or at least one other non-child frame (@pxref{Child Frames})
+on that terminal exists.  In the former case, if @var{frame} is
+selected, it will select the first visible ancestor of @var{frame}
+instead.  In the latter case it will make another non-child frame on
+that terminal visible and the new top frame (@pxref{Frames}) of that
+terminal.  In either case, it will remove all child frames with
+@var{frame} as their ancestor from display.
 @end deffn
 
   The visibility status of a frame is also available as a frame
-parameter.  You can read or change it as such.  @xref{Management
+parameter.  You can read or change it as such.  @xref{Frame Interaction
 Parameters}.  The user can also iconify and deiconify frames with the
 window manager.  This happens below the level at which Emacs can exert
 any control, but Emacs does provide events that you can use to keep
@@ -3336,14 +3393,16 @@ This function raises frame @var{frame} (default, the selected frame)
 above all other frames belonging to the same or a lower z-group as
 @var{frame}.  If @var{frame} is invisible or iconified, this makes it
 visible.  If @var{frame} is a child frame (@pxref{Child Frames}), this
-raises @var{frame} above all other child frames of its parent.
+raises @var{frame} above all other child frames of its parent.  For
+non-child frames on a text terminal this function has no effect.
 @end deffn
 
 @deffn Command lower-frame &optional frame
 This function lowers frame @var{frame} (default, the selected frame)
 below all other frames belonging to the same or a higher z-group as
 @var{frame}.  If @var{frame} is a child frame (@pxref{Child Frames}),
-this lowers @var{frame} below all other child frames of its parent.
+this lowers @var{frame} below all other child frames of its parent.  For
+non-child frames on a text terminal this function has no effect.
 @end deffn
 
 @defun frame-restack frame1 frame2 &optional above
@@ -3363,7 +3422,8 @@ true) that of @var{frame2}.  Hence the position of @var{frame2} in its
 display's Z (stacking) order relative to all other frames excluding
 @var{frame1} remains unaltered.
 
-Some window managers may refuse to restack windows.
+Some window managers may refuse to restack windows.  This function has
+not been implemented on text terminals yet.
 @end defun
 
 Note that the effect of restacking will only hold as long as neither of
@@ -3378,25 +3438,14 @@ function @code{frame-list-z-order} (@pxref{Finding All Frames}).
 
 @defopt minibuffer-auto-raise
 If this is non-@code{nil}, activation of the minibuffer raises the frame
-that the minibuffer window is in.
+that the minibuffer window is in.  This function has no effect on text
+terminals.
 @end defopt
 
   On window systems, you can also enable auto-raising (on frame
 selection) or auto-lowering (on frame deselection) using frame
 parameters.  @xref{Management Parameters}.
 
-@cindex top frame
-  The concept of raising and lowering frames also applies to text
-terminal frames.  On each text terminal, only the top frame is
-displayed at any one time.
-
-@defun tty-top-frame &optional terminal
-This function returns the top frame on @var{terminal}.  @var{terminal}
-should be a terminal object, a frame (meaning that frame's terminal),
-or @code{nil} (meaning the selected frame's terminal).  If it does not
-refer to a text terminal, the return value is @code{nil}.
-@end defun
-
 
 @node Frame Configurations
 @section Frame Configurations
@@ -3662,14 +3711,17 @@ Customizing the following option can be useful to tweak the behavior of
 This option tells Emacs how to proceed when it is asked to iconify a
 child frame.  If it is @code{nil}, @code{iconify-frame} will do nothing
 when invoked on a child frame.  If it is @code{iconify-top-level}, Emacs
-will try to iconify the top-level frame that is the ancestor of this
-child frame instead.  If it is @code{make-invisible}, Emacs will try to
-make this child frame invisible instead of iconifying it.
+will try to iconify the root frame of this child frame instead.  If it
+is @code{make-invisible}, Emacs will try to make this child frame
+invisible instead of iconifying it.
 
 Any other value means to try iconifying the child frame.  Since such an
 attempt may not be honored by all window managers and can even lead to
 making the child frame unresponsive to user actions, the default is to
-iconify the top level frame instead.
+iconify the root frame instead.
+
+On a text terminal the only feasible values are @code{nil} and
+@code{make-invisible}.
 @end defopt
 
 
index d212e3e53c9093e7095adf3a187620b49facad86..6ad524f05240de47d75986e705903d66f0e0acf7 100644 (file)
@@ -3355,8 +3355,26 @@ max_child_z_order (struct frame *parent)
   return z_order;
 }
 
+/* Return true if and only if F and all its ancestors are visible.  */
+
+static bool
+frame_ancestors_visible_p (struct frame *f)
+{
+  while (f)
+    {
+      if (!FRAME_VISIBLE_P (f))
+       return false;
+      else
+       f = FRAME_PARENT_FRAME (f);
+    }
+
+  return true;
+}
+
 /* Return a list of all frames having root frame ROOT.
-   If VISIBLE_ONLY is true, return only visible frames.  */
+
+   If VISIBLE_ONLY is true, return only frames that are visible and have
+   visible ancestors only.  */
 
 static Lisp_Object
 frames_with_root (struct frame *root, bool visible_only)
@@ -3366,8 +3384,9 @@ frames_with_root (struct frame *root, bool visible_only)
   FOR_EACH_FRAME (tail, frame)
     {
       struct frame *f = XFRAME (frame);
+
       if (root_frame (f) == root
-         && (!visible_only || FRAME_VISIBLE_P (f)))
+         && (!visible_only || frame_ancestors_visible_p (f)))
        list = Fcons (frame, list);
     }
   return list;
@@ -3428,7 +3447,7 @@ frames_in_reverse_z_order (struct frame *f, bool visible_only)
   return frames;
 }
 
-/* Raise of lower frame F in z-order.  If RAISE is true, raise F, else
+/* Raise or lower frame F in z-order.  If RAISE is true, raise F, else
    lower f.  */
 
 void
index 693b743bf23bc32f19a5f5772322f78eeb5f5314..9166b35dbd790dad27ce16af69db84463b741382 100644 (file)
@@ -3294,22 +3294,29 @@ If omitted, FRAME defaults to the currently selected frame.
 On graphical displays, invisible frames are not updated and are
 usually not displayed at all, even in a window system's \"taskbar\".
 
-Normally you may not make FRAME invisible if all other frames are invisible,
-but if the second optional argument FORCE is non-nil, you may do so.
-
-This function has no effect on text terminal frames.  Such frames are
-always considered visible, whether or not they are currently being
-displayed in the terminal.  */)
+Normally you may not make FRAME invisible if all other frames are
+invisible, but if the second optional argument FORCE is non-nil, you may
+do so.
+
+On a text terminal make FRAME invisible if and only FRAME is either a
+child frame or another non-child frame can be found.  In the former
+case, if FRAME is the selected frame, select the first visible ancestor
+of FRAME instead.  In the latter case, if FRAME is the top frame of its
+terminal, make another frame that terminal's top frame.  */)
   (Lisp_Object frame, Lisp_Object force)
 {
   struct frame *f = decode_live_frame (frame);
 
+  XSETFRAME (frame, f);
+
   if (NILP (force) && !other_frames (f, true, false))
     error ("Attempt to make invisible the sole visible or iconified frame");
 
   if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
     FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
 
+  SET_FRAME_VISIBLE (f, false);
+
   if (is_tty_frame (f) && EQ (frame, selected_frame))
   /* On a tty if FRAME is the selected frame, we have to select another
     frame instead.  If FRAME is a child frame, use the first visible
@@ -3321,8 +3328,6 @@ displayed in the terminal.  */)
                   : next_frame (frame, make_fixnum (0)),
                   Qnil);
 
-  SET_FRAME_VISIBLE (f, false);
-
   /* Make menu bar update for the Buffers and Frames menus.  */
   windows_or_buffers_changed = 16;
 
@@ -3339,28 +3344,31 @@ for how to proceed.  */)
   (Lisp_Object frame)
 {
   struct frame *f = decode_live_frame (frame);
-#ifdef HAVE_WINDOW_SYSTEM
-  Lisp_Object parent = f->parent_frame;
 
-  if (!NILP (parent))
+  if (FRAME_PARENT_FRAME (f))
     {
       if (NILP (iconify_child_frame))
        /* Do nothing.  */
        return Qnil;
-      else if (EQ (iconify_child_frame, Qiconify_top_level))
+      else if (FRAME_WINDOW_P (f)
+              && EQ (iconify_child_frame, Qiconify_top_level))
        {
-         /* Iconify top level frame instead (the default).  */
-         Ficonify_frame (parent);
+         /* Iconify root frame (the default).  */
+         Lisp_Object root;
+
+         XSETFRAME (root, root_frame (f));
+         Ficonify_frame (root);
+
          return Qnil;
        }
       else if (EQ (iconify_child_frame, Qmake_invisible))
        {
-         /* Make frame invisible instead.  */
+         /* Make frame invisible.  */
          Fmake_frame_invisible (frame, Qnil);
+
          return Qnil;
        }
     }
-#endif /* HAVE_WINDOW_SYSTEM */
 
   if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->iconify_frame_hook)
     FRAME_TERMINAL (f)->iconify_frame_hook (f);
@@ -4008,10 +4016,18 @@ list, but are otherwise ignored.  */)
            change_frame_size (f, w, h, false, false, false);
 
          Lisp_Object visible = Fassq (Qvisibility, params);
+
          if (CONSP (visible))
-           SET_FRAME_VISIBLE (f, !NILP (Fcdr (visible)));
+           {
+             if (EQ (Fcdr (visible), Qicon)
+                 && EQ (iconify_child_frame, Qmake_invisible))
+               SET_FRAME_VISIBLE (f, false);
+             else
+               SET_FRAME_VISIBLE (f, !NILP (Fcdr (visible)));
+           }
 
          Lisp_Object no_special = Fassq (Qno_special_glyphs, params);
+
          if (CONSP (no_special))
            FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (Fcdr (no_special));
        }
@@ -7287,15 +7303,15 @@ but will not be able to display text properties inside tooltip text.  */);
               doc: /* How to handle iconification of child frames.
 This variable tells Emacs how to proceed when it is asked to iconify a
 child frame.  If it is nil, `iconify-frame' will do nothing when invoked
-on a child frame.  If it is `iconify-top-level', Emacs will try to
-iconify the top level frame associated with this child frame instead.
-If it is `make-invisible', Emacs will try to make this child frame
-invisible instead.
-
-Any other value means to try iconifying the child frame.  Since such an
-attempt is not honored by all window managers and may even lead to
-making the child frame unresponsive to user actions, the default is to
-iconify the top level frame instead.  */);
+on a child frame.  If it is `iconify-top-level' and the child frame is
+on a graphical terminal, Emacs will try to iconify the root frame of
+this child frame.  If it is `make-invisible', Emacs will try to make
+this child frame invisible instead.
+
+Any other value means to try iconifying the child frame on a graphical
+terminal.  Since such an attempt is not honored by all window managers
+and may even lead to making the child frame unresponsive to user
+actions, the default is to iconify the root frame instead.  */);
   iconify_child_frame = Qiconify_top_level;
 
   DEFVAR_LISP ("expose-hidden-buffer", expose_hidden_buffer,