Gdk4 Clipboard union provider does not appear to make data available as expected

Hi,
I’m writing a custom application using python3 and gtk4, and am running into some issues with the clipboard - I suspect I’m coming across an API quirk I’ve yet to work my way around.

I want to be able to output three types of data to the clipboard:

  1. A serialised object for internal application use
  2. A text/csv dump for copying into a spreadsheet
  3. A text/plain dump for any other application

I have what appears to be error free code conforming to what I understand of the API. I have tested the text/plain output with my own code in a seperate test app for pasting, and it works. However attempting to paste into any other application that is not of my own creation does not result in pasting anything. This includes gEdit 46.2, and LibreOffice Calc.

My copy code:

    # Access the default clipboard for the application
    clipboard = Gdk.Display.get_default().get_clipboard()

    # Generate CSV data for external use
    csv_data = self.get_csv_data_for_selected_cells()

    # Generate and serialize the selected cell list and sheet reference for internal clipboard use
    selection = {
        'sheet_name': self.model.sheets[self.model.current_sheet_index]['name'],
        'selected_cells': self._all_selected_cells
    }
    serialized_selection = pickle.dumps(selection)

    # Convert serialized data to GLib.Bytes for clipboard use
    gbytes_selection = GLib.Bytes.new(serialized_selection)
    gbytes_csv = GLib.Bytes.new(csv_data)

    # Create content providers for different formats
    selection_provider = Gdk.ContentProvider.new_for_bytes("application/x-tab-selection", gbytes_selection)
    csv_provider = Gdk.ContentProvider.new_for_bytes("text/csv", gbytes_csv)
    text_provider = Gdk.ContentProvider.new_for_bytes("text/plain", gbytes_csv)  # Optionally treat CSV as plain text

    # Combine content providers into a union provider that offers multiple formats
    union_provider = Gdk.ContentProvider.new_union([selection_provider, csv_provider, text_provider])

    # Output the supported formats for debugging purposes
    print(Gdk.ContentFormats.to_string(union_provider.ref_formats()))

    # Set the union provider to the clipboard
    clipboard.set_content(union_provider)

    # Verify clipboard content by retrieving it immediately
    clipboard.read_text_async(None, self.on_retrieve_clipboard_content)

    # Set focus back to the main view
    self.view.sourceview.grab_focus()
    self.view.scrolled_window.grab_focus()

    # Attempt to retrieve and verify clipboard content again (redundancy check in case this was a focus/persistancy issue)
    clipboard.read_text_async(None, self.on_retrieve_clipboard_content)

And my paste code in a seperately running test application:

    self.clipboard.read_text_async(None, self.on_paste_text)

    def on_retrieve_clipboard_content(self, clipboard, result):
        # Read the text from the clipboard and print it for verification
        retrieved_text = clipboard.read_text_finish(result)
        if retrieved_text:
            print(f"Retrieved clipboard content: {retrieved_text}")
        else:
            print("Failed to retrieve clipboard content.")

This is an example of what I see in console output, when I trigger my copy:

application/x-tab-selection text/csv text/plain
<__gi__.GdkContentProviderUnion object at 0x7f0389561b80 (GdkContentProviderUnion at 0x555ac7a9ef90)>
Retrieved clipboard content: 42,99.0,12
56,,
,,
,4,88

Retrieved clipboard content: 42,99.0,12
56,,
,,
,4,88

When I go to paste into gEdit however, nothing pastes at all. Only when I access data through my own read_text_async calls can I get anything out of the clipboard.

I am obviously missing something fairly key, so any tips would be appreciated!

Cheers,
dalek

Hi,

Does it work with text/plain;charset=utf-8 ?

You can use the inspector → Global → Clipboard , to visualize the mimetypes and compare to what other apps (libreoffice calc, …) provide when they copy similar data.

Powerful tool, thanks for that.

Yes, text/plain;charset=utf-8 solves the problem pasting across different applications.

I also learnt through the tool that csv data is not useful clipboard material, and that tab delimited values are the standard for copy and pasting spreadsheet data.

So now I have my internal application serialisation, and a single text/plain;charset=utf8 output generated as:

tsv_writer = csv.writer(output, delimiter=‘\t’) # Use tab as the delimiter

This works great. Thanks again.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.