From b443d58497d6d2cfce83c3882ff0cf0ce45914d1 Mon Sep 17 00:00:00 2001 From: Neil Hodgson Date: Thu, 7 Apr 2022 13:08:52 +1000 Subject: Bug [#2322] Fix partial updates and non-responsive scroll bars on Xorg. Also fixes bugs [#2196] and [#2312]. --- doc/ScintillaHistory.html | 14 ++++++++++++++ gtk/ScintillaGTK.cxx | 27 +++++++++++++++++++++++++++ gtk/ScintillaGTK.h | 2 ++ src/Editor.cxx | 7 ++++++- src/Editor.h | 3 ++- 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 7ca9f9f85..7a7872ce5 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -573,6 +573,20 @@

Releases

+

+ Release 5.2.3 +

+

Release 5.2.2

diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index a1ac3adf8..877b4763a 100755 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -259,6 +259,10 @@ ScintillaGTK::~ScintillaGTK() { g_source_remove(styleIdleID); styleIdleID = 0; } + if (scrollBarIdleID) { + g_source_remove(scrollBarIdleID); + scrollBarIdleID = 0; + } ClearPrimarySelection(); wPreedit.Destroy(); if (settingsHandlerId) { @@ -1109,6 +1113,7 @@ bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { #if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv)); #endif + gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmentv), static_cast(topLine)); modified = true; } @@ -1130,6 +1135,7 @@ bool ScintillaGTK::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) { #if !GTK_CHECK_VERSION(3,18,0) gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth)); #endif + gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmenth), xOffset); modified = true; } if (modified && (paintState == PaintState::painting)) { @@ -1144,6 +1150,27 @@ void ScintillaGTK::ReconfigureScrollBars() { Resize(static_cast(rc.Width()), static_cast(rc.Height())); } +void ScintillaGTK::SetScrollBars() { + if (scrollBarIdleID) { + // Only allow one scroll bar change to be queued + return; + } + constexpr gint priorityScrollBar = GDK_PRIORITY_REDRAW + 5; + // On GTK, unlike other platforms, modifying scrollbars inside some events including + // resizes causes problems. Deferring the modification to a lower priority (125) idle + // event avoids the problems. This code did not always work when the priority was + // higher than GTK's resize (GTK_PRIORITY_RESIZE=110) or redraw + // (GDK_PRIORITY_REDRAW=120) idle tasks. + scrollBarIdleID = gdk_threads_add_idle_full(priorityScrollBar, + [](gpointer pSci) -> gboolean { + ScintillaGTK *sciThis = static_cast(pSci); + sciThis->ChangeScrollBars(); + sciThis->scrollBarIdleID = 0; + return FALSE; + }, + this, nullptr); +} + void ScintillaGTK::NotifyChange() { g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain)); diff --git a/gtk/ScintillaGTK.h b/gtk/ScintillaGTK.h index 9e9858c55..5db4ed3a5 100755 --- a/gtk/ScintillaGTK.h +++ b/gtk/ScintillaGTK.h @@ -82,6 +82,7 @@ class ScintillaGTK : public ScintillaBase { bool repaintFullWindow; guint styleIdleID; + guint scrollBarIdleID = 0; FontOptions fontOptionsPrevious; int accessibilityEnabled; AtkObject *accessible; @@ -133,6 +134,7 @@ private: void SetHorizontalScrollPos() override; bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) override; void ReconfigureScrollBars() override; + void SetScrollBars() override; void NotifyChange() override; void NotifyFocus(bool focus) override; void NotifyParent(Scintilla::NotificationData scn) override; diff --git a/src/Editor.cxx b/src/Editor.cxx index e7459e477..d5e6a92ff 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1861,7 +1861,7 @@ long Editor::TextWidth(uptr_t style, const char *text) { // Empty method is overridden on GTK+ to show / hide scrollbars void Editor::ReconfigureScrollBars() {} -void Editor::SetScrollBars() { +void Editor::ChangeScrollBars() { RefreshStyleData(); const Sci::Line nMax = MaxScrollPos(); @@ -1885,6 +1885,11 @@ void Editor::SetScrollBars() { //Platform::DebugPrintf("end max = %d page = %d\n", nMax, nPage); } +void Editor::SetScrollBars() { + // Overridden on GTK to defer to idle + ChangeScrollBars(); +} + void Editor::ChangeSize() { DropGraphics(); SetScrollBars(); diff --git a/src/Editor.h b/src/Editor.h index a430a23d4..095131c76 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -413,7 +413,8 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void SetHorizontalScrollPos() = 0; virtual bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) = 0; virtual void ReconfigureScrollBars(); - void SetScrollBars(); + void ChangeScrollBars(); + virtual void SetScrollBars(); void ChangeSize(); void FilterSelections(); -- cgit v1.2.3