1. 程式人生 > 實用技巧 >X window selection --- xclip

X window selection --- xclip

原文(英文) url:https://encyclopedia.thefreedictionary.com/X+Window+selection

本文為筆者的翻譯,紅色部分為筆者增加的批註。

文章目錄

Selections, cut buffers, and drag-and-drop(拖放)X window 系統中用於允許使用者將資料從一個視窗傳輸到另一個視窗的機制。當用戶在一個視窗選擇文字或一些其他的資料,而在另一個視窗貼上時使用 Selections

cut buffer 。當用戶在一個視窗中選擇了某個內容,然後單擊 selection 並將其拖放到另一個視窗時使用 Drag-and-drop

由於這兩個視窗可以由兩個不同的應用程式處理,因此這些機制需要兩個不同的客戶機連線到同一個X server來交換資料。X Window 核心協議包括一些特定於 selection 交換的請求和事件,但傳輸主要是使用事件傳送和視窗屬性完成的,它們不是特定於 selection 傳輸的。

可以傳輸不同型別的資料:通常是文字,但也可以是 p_w_picpath、數字、物件列表等。在下面,只考慮文字傳輸的情況。

Active and passive selections (主動和被動selection)

傳輸資料的方法可分為主動和被動兩種,使用哪種傳輸方式取決於處理所選資料的客戶端是否必須主動參與向請求資料的客戶端傳送資料:

Passive (被動)

當某些資料被選中時,處理此選擇的視窗的客戶端將它傳輸到其他地方,而不再需要關心它;

Active (主動)

將資料傳遞給客戶需要客戶 “持有(holding)” selection 主動參與交換;

Selectionsdrag-and-drop主動機制:在視窗中選擇了一些文字後,處理視窗的客戶端必須主動支援將資料傳輸到請求它的應用程式的協議。相比之下,cut buffers是一種被動機制:在某些文字被選中後,它被傳輸到剪下緩衝區,即使處理該視窗的應用程式終止並且該視窗被銷燬,它也會保留在那裡。

主動機制的一個優點可以在傳輸之前將資料轉換為不同的格式。特別是,接收資料的客戶端可以請求將選擇資料轉換為合適的形式。如果傳送客戶機拒絕這樣做,接收方可以請求一種不同的格式。例如,一段呈現HTML程式碼的文字可以作為文字傳輸給只能處理文字的請求程式,但是如果請求程式能夠處理它,也可以作為HTML程式碼傳輸這種格式的協商不能由被動機制完成,在這種機制中,持有 selection(併為其提供語義)的客戶端將selection傳輸到請求它的客戶端並不涉及進一步的傳輸

主動機制的另一個優點是,可以通過一系列(資料塊)傳輸而不是單個傳輸來傳輸大量資料被動機制要求將所有資料從selection所有者轉移到某個地方(剪貼快取區),然後再轉移到請求它的客戶端

被動機制的優點是即使在持有資料的客戶端終止之後,也可以完成傳輸。這在主動機制中是不可能的,因為主動機制要求持有資料的客戶端積極地參與傳輸。

Selections

X Window 系統支援任意數量的選擇;每個選擇都由一個字串(更準確地說,一個原子)標識。最常用的selection是PRIMARY selection選擇。

以下是針對selection轉移的請求,雖然轉移也涉及到其他請求:

  1. 請求知道哪個視窗擁有selection (請求知道 selection 的擁有者是哪個視窗)
  2. 請求設定擁有selection的視窗
  3. 請求轉換selection

selection 的所有者通常是所選文字所在的視窗(如果有的話)。當用戶在視窗中選擇一些文字時,處理該視窗的客戶機必須告訴伺服器該視窗是所選內容的所有者。

當用戶試圖將選擇貼上到另一個視窗時,該視窗的處理程式將啟動一個協議,以便從另一個客戶端獲取所選文字。該協議涉及上述列表中的第二個和第三個請求,並沒有由X協議指定,而是作為 Inter-Client Communication Convention Manual (客戶端間通訊約定手冊) (ICCCM)中的約定。

特別是,目標客戶端首先詢問伺服器哪個視窗擁有所選內容。然後這兩個客戶端通過伺服器傳輸選擇。這種交換涉及到視窗的一個屬性,即附加到視窗的任意資料段。如果選擇的內容被認為足夠小,可以一次全部轉移,會按照以下步驟進行:

  1. selection 的接收者請求轉換選擇,指定視窗的屬性(這可能是需要貼上文字的視窗)
  2. 作為響應,伺服器向 selection 的當前所有者傳送SelectionRequest事件;
  3. 所有者將選中的文字放在請求者通過向伺服器傳送ChangeProperty請求指定的視窗屬性中
  4. 所有者向伺服器傳送一個請求,向請求者傳送一個SelectionNotify,以通知所選內容已被傳輸
  5. 請求者現在可以通過向伺服器傳送一個或多個GetProperty請求來讀取視窗屬性中的選擇;
  6. 請求者銷燬該屬性;如果所有者要求被告知這一點,它將被髮送一個PropertyNotify事件。

圖1 selection的接收者/請求者、擁有者與X server 之間的互動

圖1 selection的接收者/請求者、擁有者與X server 之間的互動

此圖是根據自己的理解繪製,可能存在錯誤,若發現,請在評論中提醒或私信我改正。

如果內容很大,就應該分塊傳輸。在這種情況下,兩個客戶機都表示對PropertyNotify事件感興趣:通過這種方式,選擇所有者知道什麼時候讀取了選擇,請求者知道什麼時候在屬性中放置了另一個塊。

Clipboard

最常用的selection是PRIMARY,在使用者選擇某些資料時使用。CLIPBOARD 選項用於當用戶選擇一些資料並顯式地請求將其“複製”到剪貼簿時,例如通過呼叫應用程式的“編輯”選單下的“複製”,剪貼簿選擇將被使用。一個“貼上”的相關請求會導致使用剪貼簿選擇的資料。

在核心協議的級別上,PRIMARY 和 CLIPBOARD 的選擇沒有區別。但是xclipboard客戶端使它們的行為有所不同。特別是,當另一個客戶端斷言CLIPBOARD 選擇的所有權時,這個程式會請求並在一個視窗中顯示它。對這個選擇的任何進一步請求都由xclipboard處理。這樣,選擇的內容在客戶端複製後可以儲存下來。

Cut buffer.s

Cut buffers是傳輸資料的另一種機制,特別是傳輸選定的文字。它們是根視窗(root window)的視窗屬性,名為 CUT_BUFFER1,等等。與 selections 不同,cut buffers不涉及客戶端之間的直接互動。相反,當在視窗中選擇文字時,視窗所有者將該文字複製到名為CUT_BUFFER1的根視窗的屬性中。當用戶將文字貼上到另一個視窗時,視窗所有者將讀取根視窗的此屬性。

xcutsel 程式在selections 和 cut buffers之間傳輸資料,xcb 程式允許對 cut buffers 進行各種訪問。

cut buffers目前在考慮廢棄。

XDND

X Window 系統中的Drag-and-drop是由Xdnd約定控制的。當用戶將選中的文字拖放到視窗中並釋放滑鼠按鈕時,就會按照primary selection進行資料交換。由於在drag過程中發生的事情,Drag-and-drop 變得更加複雜。也就是說,當用戶將selection拖動到桌面或視窗的不同部分時,使用者希望能夠判斷文字是否可以drop。特別是,目標應該顯示是否接受放下的視覺反饋,游標應該改變以指示將要採取的動作;複製或移動。

在Xdnd協議中,選中文字並開始拖動的視窗稱為source;游標懸停在上面的視窗稱為目標視窗。源和目標之間的通訊是由源驅動的,因為源“抓取”了游標。因此,源和目標之間的交換是必要的,目的是讓目標甚至知道拖放正在發生。由於源決定遊標的形狀,因此源必須接收來自目標的響應,以便更新遊標。此外,由於目標可能需要畫一個投彈瞄準器來指示空投將在何處發生,並且由於接受空投可能取決於游標的確切位置,因此在游標移動時必須重複進行這種交換。事實上,即使游標不移動,也必須交換訊息,以便在游標接近觀察區域的邊緣時允許目標滾動。否則,使用者將只能拖放到目標的可見部分。

程式可以通過建立一個名為XdndAware的屬性來宣告視窗可以成為drop的目標,該屬性包含程式所支援的協議的最高版本。這樣,支援新版本的應用程式就可以回到舊版本,以便正確地互操作。此外,所有編寫的不支援Xdnd的應用程式將被忽略。

當游標進入目標視窗時,源檢查該視窗上是否存在XdndAware屬性。如果這個屬性存在,交換開始:

  • 源通過傳送一個事件XdndEnter來告訴目標,在拖放一些資料的同時,游標已經進入了目標
  • 通過檢視這個事件,並可能通過與源的進一步互動,目標可以找到被拖動的資料型別(文字、p_w_picpath 等)

當游標在目標視窗內時:

  • 源傳送XdndPosition事件來告訴目標游標當前的位置
  • 目標響應XdndStatus事件,以告訴源是否可以將資料刪除到當前位置
  • 當游標離開視窗或按鈕被釋放時,源傳送一個訊息XdndLeave或XdndDrop

如果使用者drop,目標像往常一樣從源請求選擇。當選擇的傳輸結束時,目標傳送一個XdndFinishevent來告訴源傳輸已經成功。

總之,協議是由源驅動的,它讓目標知道游標發生了什麼。作為迴應,目標告訴源是否接受drop。當用戶釋放滑鼠按鈕時,也必須通知目標,因為此事件啟動了對選擇的常規請求,這是由目標驅動的協議。

上面是對拖放的Xdnd約定的描述。在 Motif, OffiX 和 Amulet.中使用不同的 drag-and-drop 約定。

Programs

以下程式專門操作資料傳輸機制:

  • xcutsel 將資料從selection傳輸到cut buffers,反之亦然
  • xclipboard、glipper (Gnome)和klipper (KDE)都是剪貼簿管理器,也可能是wmcliphist
  • xcb 顯示剪下緩衝區的內容,並允許使用者對其進行操作
  • xselection, xclip, xsel and xcopy是將資料複製到或從X selection中複製的命令列程式。
    xcopy有一個冗長選項,可以幫助除錯X selection issues。
  • synergy 是一個跨平臺工具,允許您跨執行多個作業系統的多臺計算機共享剪貼簿
  • Xfce4 -clipman-plugin是一個“用於Xfce4面板的剪貼簿歷史外掛”,也是一個剪貼簿管理器
  • xtranslate 在多語言字典的Xselection中查詢單詞
  • autocutsel 同步cut buffer和 selection buffer

See also

References

  1. Zawinski, J. W. (2002). X selections, cut buffers, and kill rings. Retrieved July 13, 2010, from http://www.jwz.org/doc/x-cut-and-paste.html
(本文完)