Next: , Previous: , Up: Frames   [Contents][Index]


29.14 子フレーム

子フレームはウィンドウ(Windowsを参照)と“通常”のフレームとの中間にあるオブジェクトです。ウィンドウのよように所属するフレームにアタッチされますが、ウィンドウとは異なり互いにオーバーラップすることができます。子フレームの1つのサイズや位置を変更しても兄弟となる他の子フレームのサイズや位置は変化しません。

仕様により子フレームの作成や変更を行う操作は特別な関数やカスタマイズ可能な変数ではなくフレームパラメーター(Frame Parametersを参照)の助けを借りて実装されています。子フレームはグラフィカル端末でのみ意味があることに注意してください。

子フレームを新たに作成したり通常のフレームを子フレームに変換するためには、そのフレームのparent-frameパラメーター(Frame Interaction Parametersを参照)にすでに存在するフレームをセットします。このパラメーターで指定されたフレームは、パラメーターが変更やリセットされるまでフレームの親フレームになります。これにより技術的には子フレームのウィンドウシステムのウィンドウは、親フレームのウィンドウシステムのウィンドウの子ウィンドウになります。

parent-frameパラメーターはいつでも変更できます。これを他のフレームにセットすれば子フレームがreparent(親を変更)されます。別の子フレームにセットすればフレームをネストされた(nested)子フレームにします。にセットすればフレームの状態をトップレベルのフレーム(ウィンドウシステムのウィンドウがディスプレイーのルートウィンドウの子であるようなフレーム)にリストアします。

子フレームは任意にネスト(入れ子)させることができるので、フレームは子フレームと親フレームの両方になることができます。また子フレームと親フレームの相対的な役割はいつでも逆転させることができます(たとえ子フレームを親フレームより十分小さいサイズに保つことが通常はよいアイデアであるとしても)。フレームをそのフレームの祖先にしようと試みるとエラーがシグナルされます。

ほとんどのウィンドウシステムは親フレームのネイティブエッジ(Frame Geometryを参照)で子フレームをクリップします(これらのエッジの外側は通常は不可視になる)。子フレームのパラメーターlefttopは親のネイティブフレームの左上隅から相対的な位置を指定します。親フレームがリサイズされたとき、この位置は概念的には変更されません。

NSビルドは親フレームのエッジで子フレームをクリップしないので、子フレーム自身が可視であっても親フレームを隠さないように配置することができます。

通常は親フレームを移動することにより、すべての子フレームとその子孫も相対的な位置が変化しないように一緒に移動されます。フックmove-frame-functions (Frame Positionを参照)は子フレームの親フレームにたいする相対的な位置が変化したときだけ実行されます。

親フレームがリサイズされた際には、子フレームは概念的には以前のサイズと親フレームの左上隅からの相対的な位置を保ちます。これは親フレームが縮小されると子フレームが(部分的に)不可視になるかもしれないことを意味しています。親フレームのリサイズ時に常に子フレームを比例してリサイズおよび再配置するためにパラメーターkeep-ratioを使用できます(Frame Interaction Parametersを参照)。これにより親フレームが縮小された際にフレームの一部が隠されることを防ぐことができます。

可視な子フレームは常に親フレームの最上位に表示されるので、親フレームの下位に表示可能なNSビルド以外では親フレームの一部を隠すことになります。これは常に親ウィンドウであるデスクトップのルートウィンドウの最上位に表示されるトップレベルフレームのウィンドウシステムのウィンドウに相当します。親フレームがアイコン化されたり不可視(Visibility of Framesを参照)になったときには子フレームは不可視になります。親フレームが非アイコン化されたり可視になると子フレームは可視になります。

親フレームが削除される際には、その前に子フレームが再帰的に削除されます(Deleting Framesを参照)。この規則には1つの例外があります。子フレームが他のフレームの代理ミニバッファーフレーム(Minibuffers and Framesを参照)を果たす際には、親フレームが削除されるまで削除されずに留まります。。この時点でその子フレームをミニバッファーとして使用するフレームが残っていなければ、Emacsは子フレームの削除も試みます。理由は何であれこの削除が失敗すると、その子フレームがトップレベルのフレームになります。

子フレームがメニューバーやツールバーをもてるかどうかはウィンドウシステムやウィンドウマネージャーに依存します。ほとんどのウィンドウシステムは子フレームのメニューバーを明示的に許可していません。フレームの初期パラメーターのセッティングでメニューバーとツールバーの両方を無効にすることを推奨します。

子フレームは通常はタイトルバーやエクスターナルボーダー(Frame Geometryを参照)のようなウィンドウマネージャーの装飾を表示しません。子フレームがメニューバーやツールバーを表示しないときには他の種類のフレームのボーダーをエクスターナルボーダーのかわりに使用できます(Layout Parametersを参照)。

特にX(ただしGTK+ビルド以外)ではフレームのアウターボーダーを使用できます。MS-Windowsでは非0のアウターボ^ダーを指定することにより、幅が1ピクセルのエクスターナルボーダーが表示されます。すべてのウィンドウシステムにおいてインターナルボーダーを使用できます。いずれのケースでもフレームパラメーターundecorated (Management Parametersを参照)で子フレームにたいするウィンドウマネージャーの装飾を無効にすることを推奨します。

マウスで装飾されていない子フレームのリサイズや移動を行うためには、特別なフレームパラメーターを使う必要があります(Mouse Dragging Parametersを参照)。子フレームのインターナルボーダーが存在する場合には、そのフレームが非nildrag-internal-borderパラメーターをもっていればマウスによるフレームのリサイズに使用できます。snap-widthがセットされていれば、それは親フレームのエッジやコーナーそれぞれでフレームをスナップ(snaps)するピクセル数を表します。

マウスで子フレーム全体をドラッグするためには2つの方法があります。drag-with-mode-lineパラメーターが非nilなら、ミニバッファーウィンドウのないフレーム(Minibuffer Windowsを参照)の最下ウィンドウのモードラインエリアを通じてドラッグできます。drag-with-header-lineパラメーターが非nilなら、フレームの最上ウィンドウのヘッダーラインを通じたドラッグが可能です。

子フレームにドラッグ可能なヘッダーラインやモードラインを与えるためには、ウィンドウパラメーターmode-line-formatheader-line-format (Window Parametersを参照)を使用するのが手軽です。これらにより(drag-with-header-lineの選択時に)不要なモードラインを削除したり、フレームのドラッグと干渉するマウス感応エリアを削除できます。

親のネイティブフレームの完全に外部にフレームがドラッグで移動(マウスカーソルが行き過ぎてしまいマウスボタンのリリース時にフレームの取得が困難になる際に発生し得る)されないようにするためには、それに応じてフレームのパラメーターtop-visiblebottom-visibleをセットすることを推奨します。

top-visibleパラメーターは親のネイティブフレーム内でドラッグ中にフレームの上部で常に可視に留まるピクセル数を指定するもので、これはdrag-with-header-lineパラメーターに非nilを指定する際にセットする必要があります。bottom-visibleパラメーターは親のネイティブフレーム内でドラッグ中にフレームの下部で常に可視に留まるピクセル数を指定するもので、これはdrag-with-mode-lineパラメーターに非nilを指定する際にセットする必要があります。

display-buffer-in-child-frame (Buffer Display Action Functionsを参照)を介してバッファー表示に子フレームが使用されている際には、バッファーを表示中のウィンドウがquitされる際にフレームを適切に処理するために、フレームのauto-hide-functionパラメーターに関数をセットできます(Frame Interaction Parametersを参照)。

たとえば別のウィンドウに補完を表示する等でミニバッファーとの相互作用中子フレームを使用する際には、ミニバッファーのexit時にフレームを適切に処理するためにminibuffer-exitパラメーター(Frame Interaction Parametersを参照)が便利です。

子フレームの振る舞いは他のいくつかの点においても、トップレベルのフレームから逸脱しています。それらのいくつかを以下に挙げます:

以下の2つの関数は子フレームと親フレームで処理を行う際に役に立つかもしれません:

Function: frame-parent &optional frame

この関数はframeの親フレームをリターンする。frameの親フレームはウィンドウシステムのウィンドウがframeのウィンドウシステムのウィンドウの親ウィンドウであるようなEmacsフレーウである。そのようなフレームが存在すれば、frameはそのフレームの子フレームとみなされる。

この関数はframeに親フレームがなければnilをリターンする。

Function: frame-ancestor-p ancestor descendant

この関数はancestordescendantの祖先なら非nilをリターンする。ancestordescendantの親フレームかdescendantの親フレームの祖先なら、ancestordescendantの祖先である。ancestordescendantにはいずれも生きたフレームを指定しなければならない。

既存ウィンドウの最大の空エリア内への子フレームの描画に使用できる関数window-largest-empty-rectangleにも注意してください(Coordinates and Windowsを参照)。これは子フレームがウィンドウ内に表示されているテキストを隠さないようにするために有用です。

子フレームにたいするiconify-frameの挙動の調整に以下のオプションのカスタマイズが役に立つかもしれません。

User Option: iconify-child-frame

このオプションはEmacsにたいして子フレームのアイコン化を要求された際に処理を行う方法を指定する。nilならiconify-frameが子フレームに呼び出された際には何も行わない。iconify-top-levelなら子フレームの祖先であるトップレベルのフレームをアイコン化する。make-invisibleならアイコン化せずに子フレームを不可視にしようと試みる。

その他の値は子フレームのアイコン化を試みることを意味する。そのような試みはすべてのウィンドウマネージャーで許容されるとはかぎらず、子フレームがユーザーのアクションに無応答になることさえあり得るので、デフォルトではトップレベルのフレームをアイコン化する。