Next Generation Klipper

A few weeks ago I contacted Thomas Pfeiffer with the idea to design a new user interface for Klipper in Plasma 5.1. Surprisingly he informed me that a discussion was already started in the KDE Forums. Which is awesome as that means there was already some ideas on how the user interface could look like. Last week the number of new bug reports for KWin get lower so I started to look into Klipper for 5.1.

The old Klipper

The user interface of Klipper is based on a context menu and this restricts the possible interaction patterns. The task of Klipper is to hold a history of clipboard items and allow the user to select an old clipboard item and make it the current clipboard content. For this a context menu is a good solution as it allows the user to just select an item, it gets synced to the clipboard and the menu closes.

But Klipper offers more than just the clipboard history. It can perform various actions on the clipboard content:

  • Edit the clipboard content
  • Show a QR-code for the clipboard content
  • Remove content from history
  • Invoke actions (e.g. open link in browser) on clipboard content

Due to the nature of the context menu as user interface these actions can only be performed on the current clipboard item. Technically there is no reason for this restriction, but the user interface requires it. This in turn makes the usage interaction cumbersome: to show the QR-code of a previous item one needs to open Klipper, select the item – Klipper closes, open Klipper again and select the action to show the QR-code.

Also a problem with the current Klipper is that it doesn’t integrate with the environment. It sits in the notification area, but opens a QWidget styled menu. This makes Klipper an odd item in the system tray behaving different to all other items.

How Klipper should work in Plasma

A clipboard history is of course an important part of a desktop shell and thus should be a first class citizen. The user interface needs to be integrate and this means the interface needs to be provided by a Plasmoid which needs to be added to the notification area. The interface would still show a list and this is best done by providing the data in the form of a QAbstractItemModel.

As there should only be one clipboard history manager, but at the same time perhaps several user interfaces for it (e.g. one panel per screen) the QAbstractItemModel holding the data needs to be provided by a DataEngine. So overall we need to separate the user interface (Plasmoid) from the data storage (DataEngine) and turn the existing Klipper in just being the data storage.

How Klipper works internally

Internally Klipper consists of a History with HistoryItems in a circular double-linked list with a marked first item in the circle. Whenever the History changes the context menu gets repopulated on next show. Whenever the first item in the History changes Klipper syncs this item into the clipboard. This means the complete logic of Klipper interacts only with the History class. Which makes it a nice and clean interface. In a simplified class diagram Klipper looks like the following:

For creating the DataEngine we need access to the History and all items in it and put it into a QAbstractItemModel. There are two possible solutions: connect the QAbstractItemModel to the existing History or use the QAbstractItemModel as the new storage for the History instead of the own double linked list. As the current use of the History is to just mark everything as dirty and then to re-populate connecting the model to the History doesn’t sound like a good suggestion. Instead I investigated in using the model as the storage end. The design is then modified to look like the following:

To achieve this transition I first created a unit test to ensure that my transition doesn’t break the existing code. Then I created the model from scratch as well covered with unit tests and in a third step I hooked it into the existing History. With this transition both the use cases of the existing code base and the new DataEngine can be satisfied.

DataEngine, Service and co

With the model in place it’s time to make it available to Plasma. The tool of choice is the DataEngine which allows to export a model and can provide a Service allowing us to interact with Klipper. Of course it would be possible to add invokables to the model, but that would kind of destroy the design as the model is only supposed to be the data store. A Service which then interacts with our existing Klipper API is way cleaner. The task of the Service is to start ServiceJobs which will in turn interact with Klipper. Overall this looks now like this:

The Plasmoid

The last and maybe most important part of the rework is the user interface in form of a new Plasmoid. But that’s also the part I’m least interested in (perfer to work on backend) and are hoping for help on it :-) Given that the current user interface can and should only be considered as a draft. But it’s fully functional and support text and image elements, a filter (note: klipper supported filtering for quite some time, just start typing) and all the actions. But now the actions are available on each item and not just the latest one. In the current state with a vertical panel it looks like this:

Be aware that this is material for Plasma 5.1 – it won’t be part of the upcoming release. Also I should point out that it’s still possible to run the stand-alone Klipper application and that no features are removed. All global shortcuts and actions are still supported.

23 thoughts on “Next Generation Klipper”

  1. This looks really nice, finally it becomes a plasmoid. I’m excited!

    just a small OT question: what program did you draw the class diagrams in?

  2. Very nice stuff!

    A use case I struggle on a daily basis with:
    – I have sometext in “Klipper” (I marked sometext with the MMB)
    – Now I want to paste sometext, whereat I have to replace some othertext at the same time
    – If I double click othertext and then hit the MMB on the marked othertext, it just pastes othertext again… :-/

    It would be nice if here would interact some intelligence, that pastes sometext instead of othertext.

    On solution would be some kind of delay (like 2s) after which things get in the queue / can be pasted.

    Any thoughts on this?

    1. Unfortunately out of control of klipper. That would be up to the application to better set the cut selection.

        1. of course it’s the cut selection. You double click the word which results in it being selected. Klipper cannot know that you double clicked the word. That’s in the application scope. It’s the task of the application to recognize that you want to replace a word.

          1. He means that Klipper should have a one second timeout before the most recent item being selected, I think. That would have to be an option, though, cause man would that be annoying if you weren’t expecting it.

          2. Ok, I see.
            But still, klipper notices that something was just added to queue, which is immediately pasted again. Delaying this could work, but it is kind of a wild shot then…

            1. I think I got the effect Richard required, by simply checking the “ignore selection” button in “Selection and Clipboard” section of KDE 4.11 Klipper. That means for quick & dirty copy/paste, I can highlight and middle-mouse button paste it, only if I use context menu or cntrl-c copy, is Klipper involved allowing the “Paste Replaces” option. This replace highlighted, is what anyone used to Windows expects to happen, and is actually a nice way of working.

              Konqueror used to have a delete address item, which you clicked before pasting most often, to avoid having to go back/forth with clipboard or having to fiddle with edits, after pasting.

  3. I am glad to see UI improvements. But I have never used it and the clipboard history — I just need to remember one item and paste it. So it would be nice to have a setting that would disable all the resource hungry things in it.

    1. I must second this. Most users neither need nor care for a clipoard history.

      The only reason I keep it around (any why we currently need klipper) is the way the clipboard behaves when the application that you copy from is closed in between the paste.

      If you for example copy something from firefox, then close it and after that try to paste it somewhere, you get nothing, unless you have klipper around. This is unintuitive.

      So I would rather plasma or kded would take the job of keeping the last copy alive after a program closes, so that people don’t have to keep klipper lying around in memory.

      1. I would recommend to try using the clipboard history. Whenever I have to work on a non-KDE system that is by far the feature I miss most. You don’t know how much time you waste in your daily work because you have to change back and forth between applications in order to copy multiply chunks of text into input fields on webpages, for example. Or even if you use it just to remember some chunks for some time to search later it is much less tedious than taking a note each time. An absolute requirement for efficient use is that you set and learn the shortcuts to change between history items though.

    2. I’m not sure what resource hungry things you mean. But like any plasmoid you can just remove it (or stop klipper) and it will not need any resources.

        1. then use klipper. If you are not happy with these options I suggest to get your hands dirty and write code. We are addressing the need of having the clipboard working after closing with klipper.

    1. as I wrote in the forum thread and in this blog post: I’m not interested in UI, it will need someone interested to write it. Of course a 100 % matching version is not possible as in the mockup not everything is typical Plasma.

  4. Cool. I always wondered why Klipper was never a plasmoid to begin with. The only thing left is kmix in plasmoid form! Really diggin on the “little” improvements coming in Plasma 5.

  5. Great plans! A simple but really cool change would be if a searched text would be highlighted (and actually be shown) when searching in the klipper history. This might however affect the frontend only(?)

  6. Hi.
    Is there any plans to integrate Klipper with password managers? Right now, when KeePassX clears clipboard with password, the entire Klipper history disappears. Any ideas or plans how to fix this? May be some API that informs Klipper not to save next item in Klipper history?

    1. Mikhail, maybe you didn’t know, but you can edit klipper’s items and delete them by hand. I do this all the time to avoid keeping passwords in it.

      Though there’s a little bug in that sometimes you don’t see the content anymore but you can actually paste it (maybe it’s Xs clipboard). My workaround is to simply select another item from klipper.

      Of course, I make heavy use fo keyboard shorcuts, some of them customized to my liking, to make the whole process easier.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>