30.14.3 Child Frame Peculiarities

The behavior of child frames deviates from that of normal frames in a number of peculiar ways. Here we sketch a few of them:

Customizing the following option can be useful to tweak the behavior of iconify-frame for child frames.

User Option: iconify-child-frame

This option 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 root frame of this child frame instead. If it is 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 root frame instead.

On a text terminal the only feasible values are nil and make-invisible.

On text terminals exist a few restrictions with respect to reparenting: One is that a top frame (see Frames) cannot be directly made a child frame—you first have to make another root frame the new top frame of its terminal. If, on the other hand, you want a child frame to become the new top frame of its terminal, you have to make it a root frame first.

Also, the surrogate minibuffer window of any frame on a text terminal must reside on a frame with the same root frame. Reparenting will throw an error whenever it violates this restriction. It also means that it’s more tricky to make a minibuffer-less frame whose minibuffer window resides on a minibuffer-only child frame. On a GUI, Emacs proceeds as follows when a user has specified the value child-frame for the minibuffer parameter in initial-frame-alist (see Initial Frame Parameters):

  1. Create a minibuffer-only frame.
  2. Create a minibuffer-less frame with its minibuffer parameter set to the window of the minibuffer-only frame.
  3. Make the minibuffer-less frame the parent frame of the minibuffer-only frame.
  4. Delete the originally selected frame.

On a text terminal you have to perform these operations manually as sketched in the following snippet:

(let* ((selected (selected-frame))
       (mini-only
        (make-frame
         `((parent-frame . ,selected)
           (minibuffer . only)
           (left . 1) (top . -1) (width . 20) (height . 1))))
       (mini-less
        (make-frame
         (append `((parent-frame . ,selected)
                   (minibuffer . ,(minibuffer-window mini-only)))))))
  (set-frame-parameter mini-only 'parent-frame mini-less)
  (set-frame-parameter mini-less 'parent-frame nil)
  (select-frame mini-less)
  (delete-frame selected))

This means that you first have to install the minibuffer-less and the minibuffer-only frames both as child frames of the selected frame with the minibuffer parameter of the minibuffer-less frame set to the minibuffer window of the minibuffer-only frame. Then make the minibuffer-only frame a child frame of the minibuffer-less frame and make the minibuffer-less frame a new root frame. Finally, select the minibuffer-less frame and delete the originally selected frame.