Клипбордът е един от основните елементи на графичния потребителски интерфейс, но е труден за реализация. Има толкова много подводни камъни, че никога повече няма да можете да произнесете думата „copypaste“ с презрително изражение. Съществуват хиляди приложения и формати за данни. Невъзможно е да се осигури пълно конвертиране на всичко във всичко.
В някои случаи данните изобщо никъде не се записват при натискане на Ctrl+C. А Ctrl+V ще върне NULL. Shit happens, както се казва…
В някои програми може да се копира само текст, в други може да се маркира графика, другаде се поддържат файлове за копиране/вмъкване и т.н. Има много нюанси. Нека се опитаме да обърнем внимание на основните моменти на клипборда за Windows и Linux.
X11
Графичният стек на Linux е съставен от голям брой различни елементи, които са обединени в монолитна архитектура и по някакъв чудодеен начин работят съвместно без каквито и да било проблеми.
Така или иначе, клипбордът в X11 работи по по-различен начин, в сравнение с другите операционни системи. Тук се създава впечатление за две независими клипборда. Единият е чрез бързите клавиши като Ctrl+C/V (или Ctrl/Shift+Ins), а другият – чрез кликване с мишката – маркирането с мишката е напълно достатъчно – кликването с колелцето вмъква текста. Ако копирате данните в буфера с гореща клавишна комбинация, можете да ги поставяте само с клавиатурата. А ако копирате с мишката, можете да ги вмъкнете чрез клик със средното колело. Но понякога работят и двата метода, т.е. можете да копирате текста в буфера с мишката и да го поставите с клавишна комбинация.
Документацията потвърждава, че X11 наистина има няколко независими клипборда (тук те са наречени селекции). Те дори не са два, а могат да бъдат колкото си искате. Идеята е, че тези селекции по прицип представляват начина, по който клиентите комуникират помежду си. Самите клиенти трябва да решат помежду си кой буфер ще използват. Така например, ако пишете някакъв клиент за Linux, като собственик на селекция (SelectionOwner) можете да въведете собствения си буфер за клипборд и да се надявате, че останалите ще го възприемат.
Тоест, работата с клипборда в общи линии изглежда по следния начин:
- Клиентът 1 заявява на Х-сървъра, че притежава определен клипборд буфер във вид на SelectionOwner
- В някакъв момент от времето клиентът 2 можа да поиска от сървъра съдържанието на буфер 1, но в точно определен формат
- Х-сървърът получава тази заявка и я препраща към съответния собственик
- Притежателят на буфера на клипборда (клиентът) директно изпраща поисканите данни в указания формат към клиент 2, но когато или ако изобщо може (има и такива случаи)
- Клиентът 2 връща на клиента 1 потвърждение за получените данни
Всичко изглежда съвсем просто и логично, с минимално взаимодействие с ядрото на операционната система. Но в действителност може да има несъответствия и затруднения. Най-важното е, че няма абсолютно никаква гаранция, че клиент 1 някога ще изпрати исканите данни, още по-малко в указания формат.
Как така за потребителя цялата тази система изглежда като два изолирани буфера – един за горещите клавиши и един за мишката? Въпросът тук е в идентификацията на буферите. Вътрешно те са произволни номера, а външно (за клиентите) това са три варианта:
- PRIMARY – буферът на средния бутон на мишката
- SECONDARY – съществува, но днес на практика не се използва
- CLIPBOARD – буферът за Ctrl+C и Ctrl+V
Често програмите, работещи в X11, създават невидими програмни прозорци с единствената цел да задържат (прихванат) определен системен буфер. По принцип това може да се направи и с видим прозорец, но е по-лесно с невидим.
В действителност съдържанието на буфера наистина се прехвърля чрез програмни прозорци, а именно чрез запис в свойствата на прозореца (там се поставя ограничено количество данни). В този смисъл работата на буферите е подобна на тази на прозорците – в X11 няма изискване тези прозорци да работят на един и същ хост или чрез един и същ протокол. Така например на теория копирането трябва да работи в различните програми, дори ако клиентите са на различни компютри и са свързани към един и същ X сървър през интернет. Всъщност, точно така и става.
Така работят нещата в X11: той е само посредник между клиентите, който има минимално участие в прехвърлянето на данните от клипборда. X11 дори не разполага с вграден мениджър за тези данни.
Wayland
Както навярно всички знаят, за замяната на Х11 бе разработен протокола Wayland, на който се базират редица прозоречни мениджъри, и при който клипбордът работи по малко по-различен начин.
Работата с клипборда в спецификациите на Wayland е описана със същата специфична терминология (Selection – клипборд, clipboard – един от клипбордовете, уникален atom идентификатор и т.н.).
Но ако се вгледаме, всичко е направено съвсем логично и опростено.
По подобен начин е организирана и собствеността върху буфер от определен тип. Когато натиснете Ctrl+C, програмата просто взема клипборд от определен тип и заявява за наличието на данни в определен формат (например image/png, text/x-moz-url1 или text/plain). В този момент никъде не се изпращат или съхраняват данни. Така че, при липса на специален мениджър на клипборда, данните ще бъдат загубени при затваряне на прозореца на съответното приложение или при изтриването им в него.
Прихващането на буфера е разрешено само за главния прозорец. Когато някой нов прозорец прихване буфер, той получава съобщение от предишния собственик на буфера за наличността на данните и техния формат. След това идва стъпката на вмъкване на данните „от буфера“ (в кавички, защото вече разбрахме, че буферът е абстрактно понятие), т.е. данните, маркирани за копиране. И така, вторият клиент прави заявка (създава файлов дескриптор), като посочва формата, в който иска да получи данните. Този формат може да не е точно същият като горния, като в този случай той ще получи само част от данните или нищо.
Въпреки дългата си еволюция API за клипборда във Wayland далеч не е съвършен и тази подсистема все още се нуждае от външен мениджър или програмна библиотека, за да работи правилно.
Windows
Windows прилага същата концепция за „собственик на буфер“. Собственикът е всяко приложение, което е изпратило информация в буфера по стандартния начин. Поддържат се следните системни извиквания:
- OpenClipboard(hwnd) изпраща информация за прозореца, който трябва да стане новият собственик на буфера.
- EmptyClipboard() изтрива предишното съдържание от буфера
- SetClipboardData() за всяка част от данните, които искате да поставите в буфера (по исторически причини това извикване може да се използва дори от програми, които не разполагат с буфер)
- CloseClipboard() сигнализира за края на обработката на данни
- Честито, вие сте новият собственик на буфера
При опит на прозорец на трета страна да получи достъп до буфера неговият собственик получава няколко съобщения. Сред тях могат да бъдат WM_RENDERFORMAT (забавено визуализиране на данните за буфера, докато не бъдат директно поискани – разгледано по-долу), WM_RENDERALLFORMATS (част от последователността за унищожаване на прозореца, ако той все още притежава клипборда при унищожаването му) или WM_DESTROYCLIPBOARD (изчистване съдържанието на буфера).
Схемата за начин а за прочитане на данните от клипборда е приблизително следната:
- Извикването OpenClipboard(hwnd) изпраща информация за прозореца, който прочита данни от клипборда
- Извикването GetClipboardData() за получаването на данните от клипборда
- Извикването CloseClipboard() за индикация, че четенето на данни е приключило
Според Реймънд Чен, служител на Microsoft с 25-годишен стаж, ако всички използват препоръчаната по-горе схема, Windows ще работи както трябва. За съжаление програмите на трети страни винаги се опитват да нарушат конвенцията, а API позволява запис в чужд буфер (в случая клипборд). Това води до проблеми.
Това е приблизително начинът, по който работи и клипбордът на macOS (всъщност изобретателите на концепцията за клипборда се смятат създателите на компютъра Mac/Lisa, а за Mac има отлични мениджъри с многомесечно търсене в историята като много добри примери за това са ClipBuddy, Alfred и Raycast).
Освен това в ОС Windows 10/11 има Linux-подобен начин за работа с клипборда, при който се използва интересен подход – данните никъде не се записват, а само се отбелязват като достъпни, което е направено предимно за икономия на памет. Това е споменатият по-горе метод за отложено рендиране WM_RENDERFORMAT. И именно това е причината, ако в клипборда на Windows бъде копиран голям диапазон от клетки на Excel, а след това се направи опит тази информация да бъде вмъкната в текстов вид, то нищо не се получава и всичко приключва неудачно. И още, във Windows 10, през месец юни 2022 година, с едно от обновяванията бе въведено ограничение от 30 секунди за отложеното рендиране. Ако в продължение на това време данните не успеят да се конвертират в новия формат, в който трябва да бъдат вмъкнати, то клипбордът връща NULL.
Заключение
По този начин клипбордът е абстракция от високо ниво, която описва на разбираем език механизма за прехвърляне на данни между програмите ( клиентите, прозорците). В Linux изобщо няма буфер, там не се копира нищо, данните само се маркират за прехвърляне. Това е много интелигентен подход – потреблението на памет се свежда до нула.
Недостатъкът също е ясен – когато затворите оригиналния прозорец, информацията от клипборда също ще бъде загубена и няма да може да бъде вмъкната никъде другаде (въпреки че специалните клипборд мениджъри решават този проблем).
В другите операционни системи е решено да се жертва малка част от производителността (и от паметта) в името на удобството на потребителя, тъй като копирането и вмъкването са едни от най-използваните функции от обикновените хора, а загубата на данни е неприемлива.
Интересно е, че авторът на оригиналната статия не се спира на конкретните клипборд мениджъри, които многократно улесняват работата на потребителите. За Linux дистрибуциите това са CopyQ, Kupfer (просто перфектен за Linux Mint), Diodon, Klipper и други.
За операционната система Windows клипборд мениджърите също са много, като сред тях отново е CopyQ, следван от ClipClip, ClipMate и ClipX. Последният ClipX има най-много положителни препоръки и почти всички се насочват именно към него. Той запомня цялата история на данните от клипборда, включително изображения, клетки на електронни таблици и т.н.
Програмите от този род силно ускоряват въвеждането на текст, и намаляват броя на грешките, понеже голям брой от въвежданите думи, особено ако са по-големи, се избират от удобен списък и няма нужда да се въвеждат чрез клавиатурата или микрофона. По този начин се осигурява една много по-удобна и комфортна работа с персоналния компютър.