Итак буфер обмена, что вы о нем знаете? Да скорее всего ничего, черный ящик, данные туда входят, а потом выходят, а вы когда-нибудь задумывались каким образом так получается что вы копируете текст из какого-нибудь офисного пакета который к примеру содержит заголовки разных уровней, определенный шрифт итд, а потом вставляете его в месенджер и он выглядит как обычный plain text. 

Как же реализовать возможность копировать данные в одних программах, а затем вставлять их в другие, если между этими программами нет никакой связи, ведь довольно часто программа имеет специфичные только для нее данные, к примеру те же дорожки из KDENLive или же любого другого видеоредактора.

Или скопировать картинку в файловом менеджере, а вставить в telegram.

Устройство

Первое что пришло мне в голову, наверное данные хранятся в буфере обмена вместе с типом, и парсятся при вставке принимающей стороной, но это слишком дорого, да и хранить в каждом приложении парсер всех форматов бред. Второе — может быть парсят иксы, но тут всё таже проблема бесконечного количества форматов, и в том числе приложения сами могут выдумывать свой собственный формат. (Вот список большинства форматов)

Так что все оказалось гораздо проще, при копировании некой информации она сохраняется в буфер обмена сразу в нескольких представлениях от самого сложного к plain/text по убыванию информативности.

«При вставке информации из буфера обмена обычно используется первый распознанный приложением формат, который будет наиболее информативен для данного приложения. Например, если текстовый процессор копирует в буфер обмена текст: в формате RTF, в виде рисунка WMF и в виде текста без форматирования, этот текст может быть вставлен в другой текстовый процессор с сохранением разметки, в графический редактор — рисунком и в простой текстовый редактор — неформатированным текстом. »

Примеры работы с основным буфером обмена

Программа демонстрирующая это находится здесь (да она выполнена в процедурном стиле в качестве моего эксперимента, разобраться в ней крайне просто, название каждого файла говорит само за себя и все они не длиннее 30ти строк), а сейчас я прокомментирую некоторые основные моменты касающиеся буфера обмена.

Представлением буфера обмена является класс Gtk.Clipboard

Так что для начала создаем объект класса 

Clipboard clb;

Инициализируем его из окна нашего приложения 

clb = window.get_clipboard(Gdk.SELECTION_CLIPBOARD);

Привязываем сигнал вставки в буфер текстового поля к нашему новому слоту

`text_viewer.buffer.paste_done.connect(paste_done);`

Код слота paste_done (срабатывает при вставке в текстовое поле)

void paste_done(Clipboard clipboard){
  print(@"$(search.get_text())");
  clb.request_contents(Gdk.Atom.intern(search.get_text(), false), get_content);
}

request_contents — Запрашивает содержимое буфера обмена и при его получении вызывает функцию (второй аргумент)

Gdk.Atom  Это тип, представляющий строку в виде индекса в таблице строк на X-сервере, а его метод intern находит или создает Atom соответствующей строке (первый аргумент) (search — поле ввода в которое можно ввести тип вставляемых данных, оно так же подсказывает большинство текстовых форматов)

Собственно колбек который будет вызван при получении буфера обмена (попахивает не блокирующей асинхронщинной)

get_content()
void get_content (Clipboard clipboard, SelectionData sd) {
	if ( sd.get_length()>0 ) {
		text_buffer.set_text( (string)(sd.get_data()) );
	} else {
		text_buffer.set_text("NOT " + search.get_text().up(), -1); 
	}
}

Ну тут всё очевидно, к нам приходит буфер обмена и его дата, если дата не пуста мы добавляем ее в textView, если пуста это означает что она не соответствует формату, который мы готовы принять, что мы и выводим.(напомню формат мы задаем в entry который умеет выдавать подсказки)

Как пользоваться

Копируете чтото из какого то приложения. Выбираете формат вводя его в search entry. Вставляете из буфера обмена в text view

Например можно скопировать из pdf редактора, и выбрать plain/text

А теперь вставляем наоборот копируем отсюда и вставляем в любой декодер

тут

И узнаем что в PDFе был unicode UTF-8. Также можно попробовать с текстом из Libre Office(это будет text/richtext) или svg картинкой.

Вспомогательный буфер

Также в иксах существует еще один буфер обмена, в него попадает всё что вы выделяете, а вставка оттуда происходит по средней клавише мыши.
Вот тут можно посмотреть пример работы с ним, это простейчая виртуальная клавиатура, все что вы печатаете в ней мышкой попадает в primary буфер обмена, комментировать там нечего, все отличается на флаг Gdk.SELECTION_PRIMARY.

А на сегодня всё, до новых встреч.