30.24 ドラッグアンドドロップ

ドラッグアンドドロップで転送されるデータは、プレーンテキストかファイルやその他のリソースを示すURLのリストであることが一般的です。テキストをドロップするとドロップした場所にテキストが挿入されますが、それが不可能ならリソースはkillリングに保存されます。

ドロップされたURLは変数dnd-protocol-alist内の適切なDNDハンドラー関数(DND handler functions)、または変数browse-url-handlersbrowse-url-default-handlersに設定された“URLハンドラー”に提供されます。いずれのタイプのハンドラーにもマッチが存在しなければプレーンテキストとみなされてバッファーに挿入されます。

Variable: dnd-protocol-alist

この変数はURLをマッチさせるregexp、およびマッチしたURLのドロップ時に呼び出されるDNDハンドラー関数からなるalist。

ハンドラー関数がdnd-multiple-handlerプロパティがセットされたシンボル(シンボルのプロパティを参照)の場合には、ドロップ時にはそのregexpにマッチするすべてのURLのリストが与えられる。このプロパティがなければ、それらのURLそれぞれにたいしてハンドラー関数が1回呼び出される。この1つ目の引数の後には実行するアクションを識別するcopymovelinkprivateaskいずれかのシンボルを指定する。

actionprivateなら、それはドロップ操作を開始したプログラムが受信者側に特定の動作を要求しない。この場合に行うべき妥当なアクションはそのURLのオープン、あるいはカレントバッファーへのコンテンツのコピーとなる。それ以外のactionは、dnd-begin-file-dragにたいするaction引数と同じ意味合いとなる。

処理が完了したら、ハンドラー関数は行ったアクションを示すシンボルをリターンしなければならない。リターンするシンボルは指定されたアクション、あるいはドロップのソースにたいして所定のアクションが実行されなかったことを伝えるシンボルprivateのいずれか。

ドロップ内の重複するアイテムのサブセットに複数のハンドラーが一致する際には、もっとも多くのアイテムにたいしてマッチするハンドラーがそのサブセットをオープンするために呼び出される。提供されたアイテムは(たとえそれらも同様にマッチしても)後続の他のハンドラーには保留される。

EmacsはテキストとURL以外のデータを受け入れるための手段は用意していません。これを可能にするためのウィンドウシステムのインターフェイスは、一貫性をもって抽象化するにはあまりに異なるからです。特定のドラッグアンドドロッププロトコルは受信者にそのような制御を拒むので、DNDハンドラーにも実行しようとするアクションにたいして影響を与えることは許されていません。X11のドラッグアンドドロップの実装は、選択の転送を使用し多くの共通点を共有する土台となる複数のプロトコルに基礎を置いており、以下の関数と変数を通じた低レベルのアクセスが提供されています:

Variable: x-dnd-test-function

この関数はEmacsがドロップを受け入れるべきかを確認するために呼び出される。以下の3つの引数で呼び出される:

  • ドラッグ中のアイテムの下にあるウィンドウ、すなわちドロップを受信するバッファーのウィンドウ。アイテムがフレームのウィンドウ以外のコンポーネント上(スクロールバー、ツールバーなど)にある場合には、フレーム自体が供される。
  • ドロップのソースによって提案されたアイテムにたいして実行するアクションを表すシンボル。movecopylinkaskのいずれか。これらのシンボルの意味はx-begin-dragの場合と同様。
  • そのアイテムが提供する選択データタイプのベクター(X選択を参照)。

この関数はドロップを拒絶するnil、あるいは実行するアクション(DNDハンドラー関数への転送など)とリクエストされた選択データタイプからなるコンスのいずれかをリターンしなければならない。このコンスでリターンされるアクションはシンボルprivateでもよく、これは実行するアクションが確定していないことを暗に示す。

Variable: x-dnd-known-types

x-dnd-test-functionの変更は一般的に保証されていない。ドロップを受け入れるためのデフォルトの基準セットはこの選択データタイプのリストを変更すれば調整できるため。要素はそれぞれシンボルであり、デフォルトの“テスト関数”によってデータタイプのリストで要素の名前をもつシンボルが見つかった場合には、その関数がドロップを受け入れるよう仕向けられる。

このリストへの新たなエントリーの導入は、相手方となるハンドラー関数がx-dnd-types-alistに追加されなければ有用ではない。

Variable: x-dnd-types-alist

この変数は選択データタイプを示す文字列、およびそのタイプがドロップされた際に呼び出される関数とのalist。

これらの関数はそれぞれ3つの引数を提供する。1つ目はx-dnd-test-functionの場合のようにドロップ箇所の下にあるウィンドウかフレーム、2つ目は実行するアクション(テスト関数がリターンするアクションのいずれかかもしれない)、3つ目は選択データそれ自体(選択へのアクセスを参照)。

X11のドラッグアンドドロッププロトコルによって提供される選択データタイプは、ICCCMおよびそれに準拠するクリップボードやプライマリー選択の所有者によって提供される選択データタイプとは異なる場合があります。よくある例としては"text/plain;charset=utf-8"のようなlMIMEのタイプ名(“utf-8”の大文字小文字が異なる)から、UTF8_STRINGのような標準的なXの選択名への置き換えです。

XDSプロトコル(X Direct Save Protocol)により、プログラムがドロップするファイルにたいする命名責任を受信者に委譲することが可能になります。このようなドロップが発生すると、ドロップに応答するために別の関数が用いられて、DNDハンドラーおよび前述したX固有のインターフェイスの大部分が回避されます。

Variable: x-dnd-direct-save-function

この変数nはXDSプロトコルを用いて2ステップの手続きを経て、ドロップされたファイルの登録と命名を行う関数をセットすること。この関数はneed-namefilenameという2つの引数を受け取る。

  1. ファイルのドラッグ元であるアプリケーションは、ファイルを保存するためにEmacsにたいして完全なファイル名の提供を求める。この目的のために1つ目の引数need-nameに非nil、2つ目の引数filenameに保存するファイルのディレクトリー部分を除いた名前をセットしてdirect-save関数が呼び出される。この関数はファイルを保存するための完全に展開された絶対ファイル名をリターンする必要がある。たとえばDiredウィンドウにファイルがドラッグされれば、そのファイルのディレクトリーは当然ドロップされた場所に表示されているファイルのディレクトリーになるだろう。何らかの理由によりファイルの保存が不可能な場合には、この関数はドラッグアンドドロップ操作をキャンセルするnilをリターンする必要がある。
  2. ファイルのドラッグ元のアプリケーションは、1回目のdirect-save関数呼び出しでリターンされた名前でファイルを保存する。ファイルの保存に成功したら1つ目の引数need-namenil、2つ目の引数filenameに保存したファイルの完全な絶対ファイル名をセットして、もう一度direct-save関数を呼び出す。この関数にはファイルが保存されたという事実に鑑み、何であれ必要な処理を行うことが期待される。たとえばDiredならそこに新たなファイルを表示して、ディスプレイ上のディレクトリーを更新する必要があるだろう。

デフォルトのx-dnd-direct-save-functionx-dnd-save-direct

Function: x-dnd-save-direct need-name filename

引数need-nameが非nilで呼び出されると、この関数はファイルを保存するためにユーザーに絶対ファイル名の入力を求める。指定されたファイルがすでに存在する場合には、上書きするかどうかの入力をユーザーに追加で求めて、ユーザーが上書きに同意した場合のみ絶対ファイル名をリターンする。

引数need-namenilで呼び出された際には、カレントバッファーがDiredモード、あるいはDiredを継承する子孫の場合にはDiredの一覧リストをリバート、それ以外の場合にはfind-file (ファイルをvisitする関数を参照)を呼び出してそのファイルをvisitする。

Function: x-dnd-save-direct-immediately need-name filename

この関数はx-dnd-save-directと同様に機能するが、引数need-nameが非nilで呼び出されても、ファイルを保存するための完全なファイル名の入力をユーザーに求めずに、カレントバッファーのデフォルトディレクトリーにたいしてfilename引数を展開してリターンする(デフォルトディレクトリーにその名前のファイルが既に存在する場合に確認を求めるのは変わらず)。

カレントのウィンドウシステムでサポートされていれば、Emacsから他のプログラムへのコンテンツのドラッグも可能です。以下はこのために提供される関数です:

Function: dnd-begin-text-drag text &optional frame action allow-same-frame

関数はframeから別のアプリケーション(ドロップターゲットと呼ばれる)へのfileのドラッグアンドドロップを開始して、textがドロップされるか操作がキャンセルされるとリターンする。

actioncopymoveというシンボルのいずれかでなければならない。ここでcopyはドロップターゲットによってtextが挿入されるべきであることを意味する。movecopyと同様だが、以下のリストで説明するように呼び出し元はソースからtextも削除しなければならない。

frameはマウスボタンをカレントで押下したフレーム。nilは選択されているフレームを意味する。この関数はどのマウスボタンが何も押されていなければ即座にリターンするかもしれないので、down-mouse-1やそれに類するイベント(マウスイベントを参照)への応答として、そのイベントが発生したフレーム(クリックイベントを参照)をframeにセットして呼び出すこと。

allow-same-framenilなら、frame自体の上へのドロップを無視する。

リターン値はドロップターゲットが実際に行ったアクションを反映する。したがって(もしあれば)呼び出し側が次に行うアクションも反映する。 以下のうちのシンボルのいずれか:

copy

ドロップターゲットはドロップされたテキストを挿入した。

move

ドロップターゲットはドロップされたテキストを挿入した。呼び出し元はもし該当すればテキストの抽出元であるバッファーからtextを削除する必要がある。

private

ドロップターゲットは指定されていない何らかのアクションを行った。

nil

ドラッグアンドドロップの操作はキャンセルされた。

Function: dnd-begin-file-drag file &optional frame action allow-same-frame

この関数はframeから別のアプリケーション(ドロップターゲットと呼ばれる)へのドラッグアンドドロップ操作を開始して、fileがドロップされるか操作がキャンセルされるとリターンする。

fileがリモートファイルなら、一時的なローカルコピーを作成する。

actioncopymove、またはlink,のいずれかでなければならない。ここでcopyはドロップターゲットによってfileがオープンまたはコピーされるべきことを、moveはドロップターゲットがファイルを別の場所に移動すべきことを、そしてlinkはドロップターゲットがfileへのシンボリックリンクを作成するべきであることを意味する。fileがリモートファイルの場合にアクションとしてlinkを指定するとエラーになる。

frameallow-same-frameの意味はdnd-begin-text-drag呼び出しでの場合と同様。

リターン値はドロップターゲットが実際に行ったアクションで、以下のうちのシンボルのいずれか:

copy

ドロップターゲットはfileをオープンした、または別の場所へコピーした。

move

ドロップターゲットはfileを別の場所に移動した。

link

ドロップターゲット(通常はファイルマネージャー)はfileへのシンボリックリンクを作成した。

private

ドロップターゲットは指定されていない何らかのアクションを行った。

nil

ドラッグアンドドロップの操作はキャンセルされた。

Function: dnd-begin-drag-files files &optional frame action allow-same-frame

この関数はdnd-begin-file-dragと同様だが、filesがファイルのリストである点が異なる。ドロップターゲットが複数ファイルのドロップをサポートしていなければ、かわりに1つ目のファイルが使用される。

Function: dnd-direct-save file name &optional frame allow-same-frame

この関数の挙動は(デフォルトのアクションcopyを使用した際は)dnd-begin-file-dragと似ているが、実際にコピーする際に名前を受け付ける点が異なる。

上述した高レベルのインターフェイスは、低レベルなプリミティブの上位に実装されています。低レベルのインターフェイスx-begin-dragはテキストやファイル以外のコンテンツのドラッグにも利用できます。これには呼び出し側がサポートしたいプラットフォームそれぞれにおいて、プログラムが理解できるデータタイプおよびアクションにたいする詳細な知識が必要でしょう。

Function: x-begin-drag targets &optional action frame return-frame allow-current-frame follow-tooltip

この関数はframeからのドラッグを開始して、そのドラッグアンドドロップがドロップに成功するか、あるいは拒絶されたかのいずれにより操作終了したらリターンする。ドロップはframe以外のトップレベルのXウィンドウ(ドロップターゲットallow-current-frameが非nilなら任意のXウィンドウ)の上でマウスボタンがリリースされた際に発生する。そのドラッグアンドドロップ操作の開始時にどのマウスボタンも押されていなければ、この関数は即座にnilをリターンする。

targetsgui-get-selectiondata-type引数のような、選択されているターゲットを表す文字列のリストであり、ドロップターゲットがEmacsに要求する可能性がある(ウィンドウシステムによる選択を参照)。

actionはターゲットに推奨されているアクションを示すシンボル。XdndActionCopyXdndActionMoveのいずれか。どちらも選択コンテンツのコピーをコピーを暗に示し、XdndSelectionはドロップターゲットへのコピーだが、後者はさらにコピー後に選択コンテンツの削除を指示する。

利用できるアクションを表すシンボル、およびユーザーにそれらのアクションを選択させる際に提示する文字列との連想を示すalistでもよい。

return-frameが非nil、および最初にマウスがframeの外に移動してからEmacsフレームに移動した場合には、マウスが移動したフレームを即座にリターンする。return-frameがシンボルnowなら、最初にマウスがframeの外に移動するのを待機せずに、フレームが何であれマウスポインター配下にあればそのフレームをリターンする。return-frameは特にあるフレームから別のフレームへのコンテンツのドラッグを扱いたい際に役に立つだろう。他のプログラムへのコンテンツのドラッグも扱えるものの、すべてのシステムやウィンドウマネージャーの関数では保証されていない。

follow-tooltipが非nilの場合には、ドラッグアンドドロップ操作の間にマウスポインターが移動するたびに、(tooltip-showによって表示されるような)ツールチップの位置がマウスポインターの位置にしたがうようになる。マウスボタンがリリースされるとツールチップは非表示になる。

ドロップが拒絶されるかドロップターゲットが見つからなければ、この関数はnilをリターンする。それ以外の場合には、ターゲットが行うことを選択したアクション(ドロップターゲットがサポートしていなければactionとは異なるかもしれない)を記述するシンボルをリターンする。XdndActionCopyXdndActionMoveに加えてXdndActionPrivateも有効なリターンである。これはドロップターゲットが指定されていないアクションを選択したことを意味しており、呼び出し元はそれ以上の処理を要求されない。

呼び出し元はターゲットによって選択された処理を完遂するために、ターゲットと協力しなければならない。たとえばこの関数がXdndActionMoveをリターンしたら、呼び出し元はドラッグされたバッファーのすべてのテキスト、同様の基準が適用されるようなドラッグデータも削除すること。

関数x-begin-dragは、複数のドラッグアンドドロップのプロトコルの“舞台裏”で使用することで目的を果たしています。特定のドラッグアンドドロッププロトコルによってサポートされているか不明なコンテンツをドラッグする際には、以下の変数の値を変更してそのプロトコルをオフに切り替えることができます:

Variable: x-dnd-disable-motif-protocol

この変数が非nilならMotifのドラッグアンドドロップのプロトコルは無効化となり、それらのプロトコルしか理解していないプログラムへのドロップは機能しない。

Variable: x-dnd-use-offix-drop

この変数がnilならOffiX(旧KDE)のドラッグアンドドロップのプロトコルは無効となる。シンボルfilesなら、x-begin-dragによって与えられたターゲットのいずれかが"FILE_NAME"の場合のみOffiXプロトコルが使用される。それ以外の値の場合には、サポートされているコンテンツのドロップにOffiXプロトコルが使用される。

Variable: x-dnd-use-unsupported-drop

x-begin-dragによって与えられたリスト内に"STRING""UTF8_STRING""COMPOUND_TEXT""TEXT"のいずれかのターゲットがあれば、ドロップターゲットが何もドラッグアンドドロップのプロトコルをサポートしていなくても、Emacsは合成されたマウスイベントとプライマリー選択を用いてテキストの挿入を試みる。

そのようなドロップにおいては、Emacsがそのプライマリー選択の所有者になるという副作用がある。この変数をnilにセットすれば、このようなエミュレーションを無効にできる。


This page has generated for branch:work/emacs-30_69b16e5c63840479270d32f58daea923fe725b90, commit:5e3f74b56ff47b5bcef2526c70f53f749bbd45f6 to check Japanese translation.