子フレームはウィンドウ(ウィンドウを参照)と“通常”のフレームとの中間にあるオブジェクトです。ウィンドウのよように所属するフレームにアタッチされますが、ウィンドウとは異なり互いにオーバーラップすることができます。子フレームの1つのサイズや位置を変更しても兄弟となる他の子フレームのサイズや位置は変化しません。
仕様により子フレームの作成や変更を行う操作は特別な関数やカスタマイズ可能な変数ではなくフレームパラメーター(フレームのパラメーターを参照)の助けを借りて実装されています。子フレームはグラフィカル端末でのみ意味があることに注意してください。
子フレームを新たに作成したり通常のフレームを子フレームに変換するためには、そのフレームのparent-frame
パラメーター(フレームとの相互作用のためのパラメーターを参照)にすでに存在するフレームをセットします。このパラメーターで指定されたフレームは、パラメーターが変更やリセットされるまでフレームの親フレームになります。これにより技術的には子フレームのウィンドウシステムのウィンドウは、親フレームのウィンドウシステムのウィンドウの子ウィンドウになります。
parent-frame
パラメーターはいつでも変更できます。これを他のフレームにセットすれば子フレームがreparent(親を変更)されます。別の子フレームにセットすればフレームをネストされた(nested)子フレームにします。にセットすればフレームの状態をトップレベルのフレーム(ウィンドウシステムのウィンドウがディスプレイーのルートウィンドウの子であるようなフレーム)にリストアします。22
子フレームは任意にネスト(入れ子)させることができるので、フレームは子フレームと親フレームの両方になることができます。また子フレームと親フレームの相対的な役割はいつでも逆転させることができます(たとえ子フレームを親フレームより十分小さいサイズに保つことが通常はよいアイデアであるとしても)。フレームをそのフレームの祖先にしようと試みるとエラーがシグナルされます。
ほとんどのウィンドウシステムは親フレームのネイティブエッジ(フレームのジオメトリーを参照)で子フレームをクリップします(これらのエッジの外側は通常は不可視になる)。子フレームのパラメーターleft
とtop
は親のネイティブフレームの左上隅から相対的な位置を指定します。親フレームがリサイズされたとき、この位置は概念的には変更されません。
NSビルドは親フレームのエッジで子フレームをクリップしないので、子フレーム自身が可視であっても親フレームを隠さないように配置することができます。
通常は親フレームを移動することにより、すべての子フレームとその子孫も相対的な位置が変化しないように一緒に移動されます。フックmove-frame-functions
(フレームの位置を参照)は子フレームの親フレームにたいする相対的な位置が変化したときだけ実行されます。
親フレームがリサイズされた際には、子フレームは概念的には以前のサイズと親フレームの左上隅からの相対的な位置を保ちます。これは親フレームが縮小されると子フレームが(部分的に)不可視になるかもしれないことを意味しています。親フレームのリサイズ時に常に子フレームを比例してリサイズおよび再配置するためにパラメーターkeep-ratio
を使用できます(フレームとの相互作用のためのパラメーターを参照)。これにより親フレームが縮小された際にフレームの一部が隠されることを防ぐことができます。
可視な子フレームは常に親フレームの最上位に表示されるので、親フレームの下位に表示可能なNSビルド以外では親フレームの一部を隠すことになります。これは常に親ウィンドウであるデスクトップのルートウィンドウの最上位に表示されるトップレベルフレームのウィンドウシステムのウィンドウに相当します。親フレームがアイコン化されたり不可視(フレームの可視性を参照)になったときには子フレームは不可視になります。親フレームが非アイコン化されたり可視になると子フレームは可視になります。
親フレームが削除される際には、その前に子フレームが再帰的に削除されます(フレームの削除を参照)。この規則には1つの例外があります。子フレームが他のフレームの代理ミニバッファーフレーム(ミニバッファーとフレームを参照)を果たす際には、親フレームが削除されるまで削除されずに留まります。。この時点でその子フレームをミニバッファーとして使用するフレームが残っていなければ、Emacsは子フレームの削除も試みます。理由は何であれこの削除が失敗すると、その子フレームがトップレベルのフレームになります。
子フレームがメニューバーやツールバーをもてるかどうかはウィンドウシステムやウィンドウマネージャーに依存します。ほとんどのウィンドウシステムは子フレームのメニューバーを明示的に許可していません。フレームの初期パラメーターのセッティングでメニューバーとツールバーの両方を無効にすることを推奨します。
子フレームは通常はタイトルバーやエクスターナルボーダー(フレームのジオメトリーを参照)のようなウィンドウマネージャーの装飾を表示しません。子フレームがメニューバーやツールバーを表示しないときには他の種類のフレームのボーダーをエクスターナルボーダーのかわりに使用できます(レイアウトのパラメーターを参照)。
特にX(ただしGTK+ビルド以外)ではフレームのアウターボーダーを使用できます。MS-Windowsでは非0のアウターボ^ダーを指定することにより、幅が1ピクセルのエクスターナルボーダーが表示されます。すべてのウィンドウシステムにおいてインターナルボーダーを使用できます。いずれのケースでもフレームパラメーターundecorated
(ウィンドウ管理のパラメーターを参照)で子フレームにたいするウィンドウマネージャーの装飾を無効にすることを推奨します。
マウスで装飾されていない子フレームのリサイズや移動を行うためには、特別なフレームパラメーターを使う必要があります(マウスドラッグのパラメーターを参照)。子フレームのインターナルボーダーが存在する場合には、そのフレームが非nil
のdrag-internal-border
パラメーターをもっていればマウスによるフレームのリサイズに使用できます。snap-width
がセットされていれば、それは親フレームのエッジやコーナーそれぞれでフレームをスナップ(snaps)するピクセル数を表します。
マウスで子フレーム全体をドラッグするためには2つの方法があります。drag-with-mode-line
パラメーターが非nil
なら、ミニバッファーウィンドウのないフレーム(ミニバッファーのウィンドウを参照)の最下ウィンドウのモードラインエリアを通じてドラッグできます。drag-with-header-line
パラメーターが非nil
なら、フレームの最上ウィンドウのヘッダーラインを通じたドラッグが可能です。
子フレームにドラッグ可能なヘッダーラインやモードラインを与えるためには、ウィンドウパラメーターmode-line-format
とheader-line-format
(ウィンドウのパラメーターを参照)を使用するのが手軽です。これらにより(drag-with-header-line
の選択時に)不要なモードラインを削除したり、フレームのドラッグと干渉するマウス感応エリアを削除できます。
ユーザーが親フレームの外へフレームをマウスでドラッグすれば、親フレームのスクリーン領域外へ簡単にドラッグできます。マウスボタンを一度離してしまうと、そのようなフレームを取得するのは難しくなります。そのような状況を避けるために、フレームのパラメーターtop-visible
およびbottom-visible
(マウスドラッグのパラメーターを参照)をセットすることをお勧めします。
ヘッダーラインでユーザーにフレームをドラッグさせたければ、子フレームのtop-visible
パラメーターに数値をセットします。top-visible
に数値をセットすることによって、親フレームの上エッジを超えて子フレームの上エッジをドラッグすることが抑制されます。モードラインを介してフレームをドラッグさせたければ、bottom-visible
に数値をセットしてください。これは親フレームの下エッジを超えて子フレームの下エッジをドラッグすることを抑制します。いずれの場合でも、セットした数値は同時にドラッグの間に可視に留まる子フレーム領域の幅および高さをピクセルで指定します。
display-buffer-in-child-frame
(バッファー表示用のアクション関数を参照)を介してバッファー表示に子フレームが使用されている際には、バッファーを表示中のウィンドウがquitされる際にフレームを適切に処理するために、フレームのauto-hide-function
パラメーターに関数をセットできます(フレームとの相互作用のためのパラメーターを参照)。
たとえば別のウィンドウに補完を表示する等でミニバッファーとの相互作用中子フレームを使用する際には、ミニバッファーのexit時にフレームを適切に処理するためにminibuffer-exit
パラメーター(フレームとの相互作用のためのパラメーターを参照)が便利です。
子フレームの振る舞いは他のいくつかの点においても、トップレベルのフレームから逸脱しています。それらのいくつかを以下に挙げます:
iconify-frame
を呼び出すと子フレームにに対応するトップレベルのフレームにたいしてアイコン化を試みる。異なる挙動を得るためには、以下で説明するオプションiconify-child-frame
をカスタマイズできる。
z-group
(位置のパラメーターを参照)の変更では、同じ親をもつ子フレームのstack順だけが変更される。
mouse-autoselect-window
のカスタマイズが助けになるかもしれない(マウスによるウィンドウの自動選択を参照)。
以下の2つの関数は子フレームと親フレームで処理を行う際に役に立つかもしれません:
この関数はframeの親フレームをリターンする。frameの親フレームはウィンドウシステムのウィンドウがframeのウィンドウシステムのウィンドウの親ウィンドウであるようなEmacsフレーウである。そのようなフレームが存在すれば、frameはそのフレームの子フレームとみなされる。
この関数はframeに親フレームがなければnil
をリターンする。
この関数はancestorがdescendantの祖先なら非nil
をリターンする。ancestorがdescendantの親フレームかdescendantの親フレームの祖先なら、ancestorはdescendantの祖先である。ancestorとdescendantにはいずれも生きたフレームを指定しなければならない。
既存ウィンドウの最大の空エリア内への子フレームの描画に使用できる関数window-largest-empty-rectangle
にも注意してください(座標とウィンドウを参照)。これは子フレームがウィンドウ内に表示されているテキストを隠さないようにするために有用です。
子フレームにたいするiconify-frame
の挙動の調整に以下のオプションのカスタマイズが役に立つかもしれません。
このオプションはEmacsにたいして子フレームのアイコン化を要求された際に処理を行う方法を指定する。nil
ならiconify-frame
が子フレームに呼び出された際には何も行わない。iconify-top-level
なら子フレームの祖先であるトップレベルのフレームをアイコン化する。make-invisible
ならアイコン化せずに子フレームを不可視にしようと試みる。
その他の値は子フレームのアイコン化を試みることを意味する。そのような試みはすべてのウィンドウマネージャーで許容されるとはかぎらず、子フレームがユーザーのアクションに無応答になることさえあり得るので、デフォルトではトップレベルのフレームをアイコン化する。
Haikuで子フレームが可視なのは親フレームがアクティブなときだけであり、これはHaikuウィンドウシステムの制限によるものです。同じ制限により子フレームはトップレベルの親、すなわち階層上一番上位にある親をもたないフレームの上でのみ表示が保証されています。