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:
- The semantics of maximizing and iconifying child frames is highly window-system dependent. As a rule, applications should never invoke these operations on child frames. By default, invoking
iconify-frameon a child frame will try to iconify the top-level frame corresponding to that child frame instead. To obtain a different behavior, users may customize the optioniconify-child-framedescribed below. - Raising, lowering and restacking child frames (see Raising, Lowering and Restacking Frames) or changing the
z-group(see Position Parameters) of a child frame changes only the stacking order of child frames with the same parent. Restacking has not been implemented on text terminals. - Many window-systems are not able to change the opacity (see Font and Color Parameters) of child frames.
- Transferring focus from a child frame to an ancestor that is not its parent by clicking with the mouse in a visible part of that ancestor’s window may fail with some window-systems. You may have to click into the direct parent’s window-system window first.
- Window managers might not bother to extend their focus follows mouse policy to child frames. Customizing
mouse-autoselect-windowcan help in this regard (see Mouse Window Auto-selection). - Dropping (see Drag and Drop) on child frames is not guaranteed to work on all window-systems. Some will drop the object on the parent frame or on some ancestor instead.
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):
- Create a minibuffer-only frame.
- Create a minibuffer-less frame with its
minibufferparameter set to the window of the minibuffer-only frame. - Make the minibuffer-less frame the parent frame of the minibuffer-only frame.
- 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.