Menu

#2287 Primary clipboard not working within Scintilla widget on GTK3

Bug
closed-fixed
nobody
5
2024-11-02
2021-10-11
No

In Geany, we noticed with Scintilla 5 it's not possible to paste previously selected text with middle mouse button, i.e. using the primary clipboard.

Selecting text in the Scintilla widget and pasting it in another application works fine, also selecting text in another application and pasting it into the Scintilla widget using middle mouse button works fine.
Only selecting and pasting within the Scintilla widget does not work.

This used to work with Scintilla 3.x.

Tested and reproduced also with Scite (Version 5.1.4 Scintilla:5.1.3 Lexilla:5.1.2 compiled for GTK:3.24.30).

Discussion

  • Neil Hodgson

    Neil Hodgson - 2021-10-11

    See [#2227] which made changes in this area. An issue here is that Wayland changed clipboard mechanisms so it should be recorded whether the issue is occurring on Wayland, X, or both.

     

    Related

    Bugs: #2227

  • Enrico Tröger

    Enrico Tröger - 2021-10-11

    Sorry for the missing information.
    I'm using X11. I cannot test Wayland.

     
  • Enrico Tröger

    Enrico Tröger - 2021-10-13

    Seems like Sourceforge blocked my previous comment, so here again:

    Sorry for the missing information.
    I'm using X11. I cannot test Wayland.

     
  • Neil Hodgson

    Neil Hodgson - 2021-10-23

    The primary selection is emptied because the mouse click position is selected as the place to put the text. This can be avoided by delaying setting the new selection range until the primary selection text arrives. The attached patch does this by remembering the position of the mouse button press and applying this in the selection receive handler. It also has to apply it for an empty selection.

    diff -r 64286148d3fd gtk/ScintillaGTK.cxx
    --- a/gtk/ScintillaGTK.cxx  Fri Oct 22 15:58:17 2021 +1100
    +++ b/gtk/ScintillaGTK.cxx  Sat Oct 23 11:47:08 2021 +1100
    @@ -1563,8 +1563,8 @@
    
     void ScintillaGTK::InsertSelection(GtkClipboard *clipBoard, GtkSelectionData *selectionData) {
        const gint length = gtk_selection_data_get_length(selectionData);
    +   const GdkAtom selection = gtk_selection_data_get_selection(selectionData);
        if (length >= 0) {
    -       GdkAtom selection = gtk_selection_data_get_selection(selectionData);
            SelectionText selText;
            GetGtkSelectionText(selectionData, selText);
    
    @@ -1572,11 +1572,17 @@
            if (selection == GDK_SELECTION_CLIPBOARD) {
                ClearSelection(multiPasteMode == MultiPaste::Each);
            }
    +       if (selection == GDK_SELECTION_PRIMARY) {
    +           SetSelection(posPrimary, posPrimary);
    +       }
    
            InsertPasteShape(selText.Data(), selText.Length(),
                     selText.rectangular ? PasteShape::rectangular : PasteShape::stream);
            EnsureCaretVisible();
        } else {
    +       if (selection == GDK_SELECTION_PRIMARY) {
    +           SetSelection(posPrimary, posPrimary);
    +       }
            GdkAtom target = gtk_selection_data_get_target(selectionData);
            if (target == atomUTF8) {
                // In case data is actually only stored as text/plain;charset=utf-8 not UTF8_STRING
    @@ -1877,12 +1883,11 @@
                ButtonDownWithModifiers(pt, event->time, ModifierFlags(shift, ctrl, alt, meta));
            } else if (event->button == 2) {
                // Grab the primary selection if it exists
    -           const SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace());
    +           posPrimary = SPositionFromLocation(pt, false, false, UserVirtualSpace());
                if (OwnPrimarySelection() && primary.Empty())
                    CopySelectionRange(&primary);
    
                sel.Clear();
    -           SetSelection(pos, pos);
                RequestSelection(GDK_SELECTION_PRIMARY);
            } else if (event->button == 3) {
                if (!PointInSelection(pt))
    diff -r 64286148d3fd gtk/ScintillaGTK.h
    --- a/gtk/ScintillaGTK.h    Fri Oct 22 15:58:17 2021 +1100
    +++ b/gtk/ScintillaGTK.h    Sat Oct 23 11:47:08 2021 +1100
    @@ -34,6 +34,7 @@
        int horizontalScrollBarHeight;
    
        SelectionText primary;
    +   SelectionPosition posPrimary;
    
        GdkEvent *evbtn;
        guint buttonMouse;
    

    It is also possible to solve this by special-casing primary selection within the same instance but that may require more duplicated code.

     
    • Enrico Tröger

      Enrico Tröger - 2021-10-23

      The patch fixes the problem, pasting the primary clipboard within the
      Scintilla works again. Thanks!

      There is one detail which is different from other apps: pasting the
      clipboard contents works only once. Pasting it directly again does not
      work, probably for the same reason as you explained.

      In other apps this is possible, you can paste the previously selected
      contents multiple times as long as the selection is not changed.

       
  • Neil Hodgson

    Neil Hodgson - 2021-10-23
    • labels: --> scintilla, gtk, clipboard, primary
    • status: open --> open-fixed
     
  • Neil Hodgson

    Neil Hodgson - 2021-10-23

    Fix committed as [5f9bff].

    Behaviour could be changed to not select location of paste but that would require a larger, more complex patch.

     

    Related

    Commit: [5f9bff]

  • Neil Hodgson

    Neil Hodgson - 2021-11-12
    • status: open-fixed --> closed-fixed
     
  • Neil Hodgson

    Neil Hodgson - 2023-10-27
    • labels: scintilla, gtk, clipboard, primary --> scintilla, gtk, clipboard, primary, wayland
     
  • Cousteau

    Cousteau - 2024-11-01

    There is one detail which is different from other apps: pasting the
    clipboard contents works only once. Pasting it directly again does not
    work, probably for the same reason as you explained.

    Are there plans to fix this, or should I open a new issue? This is quite disruptive in my day-to-day usage.

     
    • Cousteau

      Cousteau - 2024-11-02

      Never mind; it seems to have been fixed in [fac2fb]. Thanks!

       

      Related

      Commit: [fac2fb]


Log in to post a comment.