Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Race using wlr_data_control to create a clipboard manager #92

Description

@davidedmundson

Our clipboard manager (klipper) works as follows:

  • On a new clipboard, we copy any text
  • If the clipboard becomes empty (typically because a client died), we paste our previously copied text
  • A user can also explicitly select an item from the history

We had this on X, and I've retrofitted wlr_data_control into it.

I've implemented wlr_data_control and all of wl-copy, wl-paste work perfectly, to some extent klipper works, but there's a race I can't fix neatly, which I think would happen for all other clipboard managers trying to do the same thing.

My race is:

first copy:

  • firefox creates a wl_data_offer
  • kwin sees it forwards it klipper which copies the text...
    (all good so far)

second copy:

  • firefox deletes its old wl_data_offer before creating a new one (unlike other toolkits, but still a valid thing to do)

  • kwin forwards this update to klipper

  • klipper knows the clipboard is empty and starts its operation to prevent an empty clipboard

  • firefox creates a new wl_data_offer and calls set_selection

  • klipper creates a new wlr_data_offer (with the old clipboard text) and calls set_selection

The compositor gets these in any order, and we end up replacing our new clipboard content with out-of-date previous clipboard contents.


Ultimately to prevent a race I think we need an additional fence like:

    <event name="selection">
        <arg name="id" type="object" interface="zwlr_data_control_offer_v1" allow_null=true>
         An integer value that increases, like the xdg_shell configure events
        <arg name="serial" type="int">
    </event>
    
    <request name="set_selection">
          <arg name="source" type="object" interface="zwlr_data_control_source_v1"
        allow-null="true"/>
        Optional serial which matches the clipboard event we're responding to. If this is out-of-date this selection will be immediately cancelled and ignored. If negative, we always apply the new selection.
        <arg name="serial" type="int"> 
    </request>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions