FR: cut/copy/paste interface for GTK

Has there been any consideration for an interface to make it easier for the developer to run cut/copy/paste clipboard actions on widget (needed for the implementation of a copy/paste menu).

Why is this needed?
Currently, you can

  • if (GTK_IS_LABEL (widget) || GTK_IS_ENTRY (widget) || GTK_IS_TEXT_VIEW (widget)) || GTK_IS_EDITABLE (widget) || ...
  • Or guint signal = g_signal_lookup ("copy-clipboard", G_OBJECT_TYPE (widget));
    to figure out, if a widget supports cut/copy/paste signals or methods. Unfortunately, both ways are only fragile options.

And once you get an interface, what are you going to do? You cannot use the same API between Label, Entry, and TextView anyway in order to get the contents of the clipboard and add them to the widget; nor you can use the same API to get the contents of the widget and put them into the clipboard. Labels aren’t even going to support copying their contents into the clipboard, unless they are selectable, and if something is determined at run time then it cannot be used as a type.

Use different callbacks for each widget that can operate on the clipboard in your application.

GTK’s text widgets (label, entry, textview) support the clipboard out of the box. For adding clipbord support to custom widgets, the interface to use is GdkClipboard.

I don’t understand that statement. This is the current situation of signals and functions. They are all consistent: signals have a widget and user data,

  • GtkLabel has
    • a copy-clipboard signal
      (void cb (GtkLabel *label, gpointer user_data))
  • GtkEntry has
    • a copy-clipboard signal
      (void cb (GtkEntry *entry, gpointer user_data))
    • a cut-clipboard signal
      (void cb (GtkEntry *entry, gpointer user_data))
    • a paste-clipboard signal
      (void cb (GtkEntry *entry, gpointer user_data))
    • gtk_editable_copy_clipboard
      (void gtk_editable_copy_clipboard (GtkEditable *editable))
    • gtk_editable_cut_clipboard
      (void gtk_editable_cut_clipboard (GtkEditable *editable))
    • gtk_editable_paste_clipboard
      (void gtk_editable_paste_clipboard (GtkEditable *editable))
  • GtkTextView has
    • copy-clipboard
      (void cb (GtkTextView *text_view, gpointer user_data))
    • cut-clipboard
      (void cb (GtkTextView *text_view, gpointer user_data))
    • paste-clipboard
      (void cb (GtkTextView *text_view, gpointer user_data))

Indeed GtkTextBuffer's API looks different:

  • void gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer, GtkClipboard *clipboard)
  • void gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer, GtkClipboard *clipboard, gboolean default_editable);
  • gtk_text_buffer_paste_clipboard (...)

In this case it would be discussable how and if to handle an interface.

Yes, they do. But they don’t share a common interface class. That means, the programmer always has to care about which widget they are working with, even though all functions/signals do the very same: copy text / cut text / paste text.
A common interface for these actions would allow the programmer to not care about the specific widget anymore.

I don’t understand why you have to care about the clipboard. It just works

It “just works” only as long as you use the accelerators or right-click menu. But there are many applications with menus like this:

image

In these cases the app devs must take good care, to check any possible case.

A quick search on Github revealed that quite some fork their flow according to the type of widget. That’s error prone because future development might introduce not yet considered widgets.

Here Thunar checks for the type to determine copy-ability.

This code is error-prone for future development, because it won’t respond to GtkTextViews or GtkLabels, that might be introduced by future programmers or add-on developers.

Here DevHelp ifs for various types:

Here evolution ifs for various types:

Here Recipes ifs for various types:

Here [whatever this app is] ifs for different types:

Here …

Here …

Here …

Here …

Here …

Here …

And thing’s get even more difficult, if you want to disable menu items, if there is no selected text.

A common interface for this common task would IMO strengthen and improve app structure and reduce code complexity. It would also suggest people to implement the interface themselves.

I don’t understand why you have to care about the clipboard. It just works

The point I’m trying to make is, it does not “just work”. You actually have to take a well-thought effort to ensure your app is working consistently.

It is still not clear what you want, and what is missing.

sorry for the late reply.

It is still not clear what you want,

A unified interface for cut/copy/paste actions of widgets.

and what is missing.

A unified interface for cut/copy/paste actions of widgets.

Example:

  • Interface function to check clipboard usability:

    • gtk_clipboardable_can_copy ()
    • gtk_clipboardable_can_paste ()
  • Interface functions to actually use the clipboard:

    • gtk_clipboardable_copy ()
    • gtk_clipboardable_paste ()
    • gtk_clipboardable_cut ()

These functions would provide a clear unified interface for copy/paste/cut action into/from clipboard.

This would not only benefit GTK itself, but also third party widgets/apps, because it encourages to actually implement the interface instead of falling for a manual approach.

Have you tried to use the clipboard.copy, clipboard.cut and clipboard.paste actions? I believe that does most of what you are asking for. These should be supported/documented on the respective text widgets. Perhaps those apps should be wanting to change their menu items to use these actions, to reduce code?

Have you tried to use the clipboard.copy, clipboard.cut and clipboard.paste actions?

I didn’t know they exist. Do you have a link to some documentation?

Hmm, they are missing on the individual widgets, but they are mentioned here: Gtk – 4.0: Overview of actions in GTK

Clipboard operations on entries, text view and labels, typically used in the context menu

Looks like it’s difficult to hook into that in case you want your own custom copy/paste actions for your custom widgets. (Couldn’t test it, as it seems not available on Gtk3)

It should be possible to implement the same actions on custom widgets using the normal way to implement actions, or pass them through to an internal GtkEntry or similar.

As I’m not using GTK4 I can’t verify at the moment, but I guess it’s the answer to this thread :slight_smile: Thank you?

I think one thing missing is that there is no way to check whether a widget responds to this action or whether the action is enabled, so maybe that would be covered by these issues:

https://gitlab.gnome.org/GNOME/gtk/-/issues/4161

https://gitlab.gnome.org/GNOME/gtk/-/issues/4162

1 Like