他のアプリケーションからユーザーが何かをEmacsの上にドロップすると、Emacsはドロップされたテキストの挿入、あるいはドロップされたURLのオープンを試みます。Emacsは常にテキストがドロップされると、そのドロップ発生時のマウスポインター位置にテキストを挿入するか、挿入が失敗した場合には(そのバッファーが読み取り専用の場合に発生し得る)そのテキストをkillリングに保存します。URLがドロップされた場合には、EmacsはそのURLと変数dnd-protocol-alistに定義されたregexp、その後は変数browse-url-handlers、browse-url-default-handlersに定義されたregexpをマッチして適切なハンドラー関数の呼び出しを試みます。もし適切なハンドラーが見つからなければ、EmacsはそのURLを平文テキストとして挿入するというフォールバック処理を行います。
この変数は(pattern . action)という形式のコンスセルのリストである。ここでpatternはドロップされた後にそのURLにたいしてマッチされるregexp、actionはドロップされたURLがpatternにマッチした場合に2つの引数で呼び出される関数で、1つ目の引数はドロップされたURL、2つ目の引数はcopy、move、link、private、askというシンボルのいずれか。
actionがprivateなら、それはドロップ操作を開始したプログラムが、そのURLでは指定されていないアクションをEmacsに行って欲しいことを意味する。この場合に行うべき妥当なアクションはそのURLのオープン、あるいはカレントバッファーへのそのURLのコンテンツのコピーとなる。それ以外のactionは、dnd-begin-file-dragにたいするaction引数と同じ意味合いとなる。
Emacsはウィンドウシステムそれぞれにたいして個別にテキストとURLの受信を実装しており、他の種別のドロップによる受信はデフォルトではサポートしていません。他の種別のデータの受信をサポートするためには、以下のX固有のインターフェイスを使用してください。
Xウィンドウシステムにおいてユーザーが別のアプリケーションからEmacsに何かをドラッグすると、そのアプリケーションはEmacsがドラッグされたデータを理解しているかどうかを告げることを期待します。このような問いにたいして何を応答するか決定するためにEmacsが用いるのが、変数x-dnd-test-function内の関数です。デフォルト値はx-dnd-default-test-functionで、これはドロップされたデータのタイプがx-dnd-known-types内に存在すればドロップを受け入れます。何か別の条件にもとづいてEmacsにドロップを許容または拒絶させたければ、x-dnd-test-functionおよびx-dnd-known-typesを変更してください。
Emacsが別のデータタイプのドロップを受け取る方法を変更したり、新たなタイプを理解するためにドロップを有効にしたい場合にはx-dnd-types-alistを変更してください。これを正しく行うためには他のアプリケーションがドラッグアンドドロップに使用するデータタイプが何なのかに関する詳細な知識が要求されます。
これらのデータタイプは通常は他のアプリケーションから提供されたX選択から入手できるスペシャルデータタイプとして実装されています。ほとんどのケースにおいて、これらはgui-set-selectionが通常許容するのと同じデータタイプかMIMEタイプのいずれかであり、それは使用される固有のドラッグアンドドロップのプロトコルに依存します。たとえば平文テキストに用いられるのは"STRING"か"STRING"のいずれかでしょう。
XウィンドウシステムでEmacsを実行する際には、XDS (X Direct
Save)というプロトコルがサポートされます。このプロトコルによってユーザーがファイルをDiredウィンドウのようなEmacsウィンドウにドラッグアンドドロップして保存ができるようになります。XDSに独特な要件に準拠するために、これらのドラッグアンドドロップの要求は特別に処理されます。つまりx-dnd-types-alistに応じて処理されるのではなく、変数x-dnd-direct-save-functionの値であるdirect-save関数(direct-save
function)によって処理されるのです。これはneed-nameおよびfilenameという2つの引数を受け取る関数である必要があります。XDSプロトコルではファイルのドラッグにたいして2段階の手続きが用いられます:
nil、2つ目の引数filenameに保存するファイルのディレクトリー部分を除いた名前をセットしてdirect-save関数が呼び出される。この関数はファイルを保存するための完全に展開された絶対ファイル名をリターンする必要がある。たとえばDiredウィンドウにファイルがドラッグされれば、そのファイルのディレクトリーは当然ドロップされた場所に表示されているファイルのディレクトリーになるだろう。何らかの理由によりファイルの保存が不可能な場合には、この関数はドラッグアンドドロップ操作をキャンセルするnilをリターンする必要がある。
nil、2つ目の引数filenameに保存したファイルの完全な絶対ファイル名をセットして、もう一度direct-save関数を呼び出す。この関数にはファイルが保存されたという事実に鑑み、何であれ必要な処理を行うことが期待される。たとえばDiredならそこに新たなファイルを表示して、ディスプレイ上のディレクトリーを更新する必要があるだろう。
x-dnd-direct-save-functionのデフォルト値はx-dnd-save-directです。
引数need-nameが非nilで呼び出されると、この関数はファイルを保存するためにユーザーに絶対ファイル名の入力を求める。指定されたファイルがすでに存在する場合には、上書きするかどうかの入力をユーザーに追加で求めて、ユーザーが上書きに同意した場合のみ絶対ファイル名をリターンする。
引数need-nameがnilで呼び出された際には、カレントバッファーがDiredモード、あるいはDiredを継承する子孫の場合にはDiredの一覧リストをリバート、それ以外の場合にはfind-file
(ファイルをvisitする関数を参照)を呼び出してそのファイルをvisitする。
この関数はx-dnd-save-directと同様に機能するが、引数need-nameが非nilで呼び出されても、ファイルを保存するための完全なファイル名の入力をユーザーに求めずに、カレントバッファーのデフォルトディレクトリーにたいしてfilename引数を展開してリターンする(デフォルトディレクトリーにその名前のファイルが既に存在する場合に確認を求めるのは変わらず)。
ウィンドウシステムが対応していれば、Emacsのフレームから他のアプリケーションウィンドウへのコンテンツのドラッグもEmacsはサポートします。
この関数はframeから別のプログラム(ドロップターゲット(drop target)と呼ばれるへのテキストのドラッグを開始して、テキストがドロップされた際のドラッグアンドドロップ操作の結果、またはドラッグアンドドロップ操作がキャンセルされたという結果をリターンする。textはドロップターゲットによって挿入されることになるテキスト。
actionはcopyかmoveというシンボルのいずれかでなければならない。ここでcopyはドロップターゲットによってtextが挿入されるべきであることを意味する。moveはcopyと同様だが、後述するように呼び出し元は更にソースからtextを削除する必要があるかもしれないことを意味する。
frameはマウスボタンをカレントで押下したフレーム。nilは選択されているフレームを意味する。どのマウスボタンも押されていなければ即座にリターンするかもしれないので、down-mouse-1やそれに類するイベント(マウスイベントを参照)の直後のみ、そのイベントが発生したフレーム(クリックイベントを参照)をframeにセットして呼び出すこと。
allow-same-frameはframe自体の上へのドロップを無視するかどうかを指定する。
リターン値はドロップターゲットが実際に行ったアクション、オプションで呼び出し元が何を行うべきかを指定する。リターン値は以下のうちのシンボルのいずれか:
copyドロップターゲットはドロップされたテキストを挿入した。
moveドロップターゲットはドロップされたテキストを挿入したが、呼び出し元はそのドロップ元(たとえばバッファー)からtextを削除する必要がある。
privateドロップターゲットは指定されていない何らかのアクションを行った。
nilドラッグアンドドロップの操作はキャンセルされた。
この関数はframeから別のアプリケーションへのfileのドラッグを開始して、そのファイルがドロップされた際のドラッグアンドドロップ操作の結果、あるいはドラッグアンドドロップ操作がキャンセルされたという結果をリターンする。
fileがリモートファイルなら、一時的なコピーを作成する。
actionはcopy、move、またはlink,のいずれかでなければならない。ここでcopyはドロップターゲットによってfileがオープンまたはコピーされるべきことを、moveはドロップターゲットがファイルを別の場所に移動すべきことを、そしてlinkはドロップターゲットがfileへのシンボリックリンクを作成するべきであることを意味する。fileがリモートファイルの場合にアクションとしてlinkを指定するとエラーになる。
frameとallow-same-frameの意味はdnd-begin-text-dragの場合と同様。
リターン値はドロップターゲットが実際に行ったアクションで、以下のうちのシンボルのいずれか:
copyドロップターゲットはfileをオープンした、または別の場所へコピーした。
moveドロップターゲットはfileを別の場所に移動した。
linkドロップターゲット(通常はファイルマネージャー)はfileへのシンボリックリンクを作成した。
privateドロップターゲットは指定されていない何らかのアクションを行った。
nilドラッグアンドドロップの操作はキャンセルされた。
この関数はdnd-begin-file-dragと同様だが、filesがファイルのリストである点が異なる。ドロップターゲットが複数ファイルのドロップをサポートしていなければ、かわりに1つ目のファイルが使用される。
この関数はdnd-begin-file-dragと似ているが、アクションのかわりにnameを指定することによって、ターゲットプログラムがその名前のコピーを作成する点が異なる(デフォルトのアクションとしてコピーを行う関数)。
上述した高レベルのインターフェイスは、低レベルなプリミティブの上位に実装されています。ファイルやテキスト以外のコンテンツのドラッグを使用が必要なら、x-begin-dragのかわりに低レベルのインターフェイスを使用してください。ただしこれらの低レベルなインターフェイスの使用にはデータタイプ、それにあなたがサポートしたいプラットフォームそれぞれにおいて、プログラムがドラッグアンドドロップを通じたコンテンツ転送に用いるアクションに関する詳細な知識が必要となるでしょう。
この関数はframeからのドラッグを開始して、そのドラッグアンドドロップがドロップに成功するか、あるいは拒絶されたかのいずれにより操作終了したらリターンする。ドロップはframe以外のトップレベルのXウィンドウ(ドロップターゲット、allow-current-frameが非nilなら任意のXウィンドウ)の上でマウスボタンがリリースされた際に発生する。そのドラッグアンドドロップ操作の開始時にどのマウスボタンも押されていなければ、この関数は即座にnilをリターンする。
targetsはgui-get-selectionのdata-type引数のような、選択されているターゲットを記述した文字列のリストであり、ドロップターゲットがEmacsに要求する可能性がある(ウィンドウシステムによる選択を参照)。
actionはターゲットに推奨されているアクションを記述したシンボル。XdndActionCopy
(選択されているXdndSelectionのコンテンツをドロップターゲットにコピー)、XdndActionMove
(XdndActionCopyのようにコピーを行い更にコピー後は選択に格納されていたものが何であれ削除が必要)のいずれか。
利用可能なアクションが記述されたシンボルと、ドロップターゲットが利用可能なアクションを選択する際にユーザーへの提示を期待する文字列を関連付けるalistでもよい。
return-frameが非nil、および最初にマウスがframeの外に移動してからEmacsフレームに移動した場合には、マウスが移動したフレームを即座にリターンする。return-frameがシンボルnowなら、最初にマウスがframeの外に移動するのを待機せずに、フレームが何であれマウスポインター配下にあればそのフレームをリターンする。return-frameは特にあるフレームから別のフレームへのコンテンツのドラッグを扱いたい際に役に立つだろう。他のプログラムへのコンテンツのドラッグも扱えるものの、すべてのシステムやウィンドウマネージャーで動作する保証はない。
follow-tooltipが非nilの場合には、ドラッグアンドドロップ操作の間にマウスポインターが移動するたびに、(tooltip-showによって表示されるような)ツールチップの位置がマウスポインターの位置にしたがうようになる。マウスボタンがリリースされるとツールチップは非表示になる。
ドロップが拒絶されるかドロップターゲットが見つからなければ、この関数はnilをリターンする。それ以外の場合には、ターゲットが行うことを選択したアクション(ドロップターゲットがサポートしていなければactionとは異なるかもしれない)を記述するシンボルをリターンする。XdndActionCopyとXdndActionMoveに加えてXdndActionPrivateも有効なリターンである。これはドロップターゲットが指定されていないアクションを選択したことを意味しており、呼び出し元はそれ以上の処理を要求されない。
呼び出し元はターゲットによって選択された処理を完遂するために、ターゲットと協力しなければならない。たとえばこの関数がXdndActionMoveをリターンしたら、呼び出し元はドラッグされたバッファーのテキストを削除すること。
Xウィンドウではx-begin-dragは、複数の異なるドラッグアンドドロップのプロトコルをサポートします。ある特定のドラッグアンドドロップのプロトコルによってサポートされているか不明なコンテンツをドラッグする際には、以下の変数の値を変更してそのプロトコルをオフに切り替えることが望ましい場合があります:
この変数が非nilならMotifのドラッグアンドドロップのプロトコルは無効化となり、それらのプロトコルしか理解していないプログラムへのドロップは機能しない。
この変数がnilならOffiX(旧KDE)のドラッグアンドドロップのプロトコルは無効となる。シンボルfilesなら、x-begin-dragによって与えられたターゲットのいずれかが"FILE_NAME"の場合のみOffiXプロトコルが使用される。それ以外の値の場合には、サポートされているコンテンツのドロップにOffiXプロトコルが使用される。
x-begin-dragによって与えられたリスト内に"STRING"、"UTF8_STRING"、"COMPOUND_TEXT"、"TEXT"のいずれかのターゲットがあれば、ドロップターゲットが何もドラッグアンドドロップのプロトコルをサポートしていなくても、Emacsは合成されたマウスイベントとプライマリー選択を用いてテキストの挿入を試みる。
そのようなドロップにおいては、Emacsがそのプライマリー選択の所有者になるという副作用がある。これが望ましくなければ、この変数をnilにセットされたドロップエミュレーションを無効にできる。