From 3ce0a475f3a28c4fe54e1b6bd3ffe0e423d5779b Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 11 Apr 2019 16:05:01 +1000 Subject: Backport: Bug [#2087]. Fix flickering when inserting primary selection on GTK between SciTE tabs. This does not allow primary selection to work between tabs as the tabs are sharing a single Scintilla and the old primary selection is unclaimed when the file is changed. This fix adds a new ReceivedClipboard method which does not try to convert the selection if received in a different format than asked for. It was the call to gtk_selection_convert that seemed to cause the flickering. ReceivedClipboard is only called from SelectionReceiver::ClipboardReceived so only occurs due to a call to RequestSelection and can not occur because of a selection_received signal. ReceivedSelection is left with its complexity in case it is needed for some other issue although it doesn't appear to be called for drag&drop, for example. Backport of changeset 7422:22864dcaca0b. --- gtk/ScintillaGTK.cxx | 42 +++++++++++++++++++++++++++++------------- gtk/ScintillaGTK.h | 4 +++- 2 files changed, 32 insertions(+), 14 deletions(-) (limited to 'gtk') diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index e3acacbf9..fd26dd2c6 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -1281,7 +1281,7 @@ public: static void ClipboardReceived(GtkClipboard *, GtkSelectionData *selection_data, gpointer data) { SelectionReceiver *self = static_cast(data); if (self->sci) { - self->sci->ReceivedSelection(selection_data); + self->sci->ReceivedClipboard(selection_data); } delete self; } @@ -1432,10 +1432,37 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio } } +void ScintillaGTK::InsertSelection(GtkSelectionData *selectionData) { + const gint length = gtk_selection_data_get_length(selectionData); + if (length >= 0) { + GdkAtom selection = gtk_selection_data_get_selection(selectionData); + SelectionText selText; + GetGtkSelectionText(selectionData, selText); + + UndoGroup ug(pdoc); + if (selection == GDK_SELECTION_CLIPBOARD) { + ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); + } + + InsertPasteShape(selText.Data(), selText.Length(), + selText.rectangular ? pasteRectangular : pasteStream); + EnsureCaretVisible(); + } + Redraw(); +} + GObject *ScintillaGTK::MainObject() const noexcept { return G_OBJECT(PWidget(wMain)); } +void ScintillaGTK::ReceivedClipboard(GtkSelectionData *selection_data) noexcept { + try { + InsertSelection(selection_data); + } catch (...) { + errorStatus = SC_STATUS_FAILURE; + } +} + void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) { try { if ((SelectionOfGSD(selection_data) == GDK_SELECTION_CLIPBOARD) || @@ -1446,22 +1473,11 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) { SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME); } else if ((LengthOfGSD(selection_data) > 0) && ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) { - SelectionText selText; - GetGtkSelectionText(selection_data, selText); - - UndoGroup ug(pdoc); - if (SelectionOfGSD(selection_data) != GDK_SELECTION_PRIMARY) { - ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); - } - - InsertPasteShape(selText.Data(), selText.Length(), - selText.rectangular ? pasteRectangular : pasteStream); - EnsureCaretVisible(); + InsertSelection(selection_data); } } // else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type), // (int)(atomUTF8)); - Redraw(); } catch (...) { errorStatus = SC_STATUS_FAILURE; } diff --git a/gtk/ScintillaGTK.h b/gtk/ScintillaGTK.h index 27f900455..b87808824 100644 --- a/gtk/ScintillaGTK.h +++ b/gtk/ScintillaGTK.h @@ -133,10 +133,12 @@ private: bool OwnPrimarySelection(); void ClaimSelection() override; void GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText); + void InsertSelection(GtkSelectionData *selectionData); public: // Public for SelectionReceiver GObject *MainObject() const noexcept; - void ReceivedSelection(GtkSelectionData *selection_data); + void ReceivedClipboard(GtkSelectionData *selection_data) noexcept; private: + void ReceivedSelection(GtkSelectionData *selection_data); void ReceivedDrop(GtkSelectionData *selection_data); static void GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *text); void StoreOnClipboard(SelectionText *clipText); -- cgit v1.2.3