Avoid styling during paint on Qt

Neil <[email protected]> Sat, 25 Jul 2026 16:38:48 -0700 (PDT)
Newsgroups gmane.comp.lib.scintilla.devel
Message-ID <[email protected]>
------=_Part_660256_567089582.1785022728929
Content-Type: multipart/alternative; 
	boundary="----=_Part_660257_1936559605.1785022728929"

------=_Part_660257_1936559605.1785022728929
Content-Type: text/plain; charset="UTF-8"

The other 3 included platforms try to perform styling before receiving 
paint events so that paints do not attempt to work on incomplete style 
information. The QueueIdleWork virtual method allows platform layers to 
schedule styling although each platform does this a bit differently.

The Qt platform layer does not currently implement QueueIdleWork so may 
have to perform styling inside paint. If this changes styles outside the 
paint area, it can cause that paint to be abandoned and a whole window 
repaint scheduled. This is inefficient and could lead to visual hitches.

Attached is a proposal for implementing QueueIdleWork on Qt as a custom 
event 'workEvent'. The implementation is closest to the Win32 platform 
layer, posting a single event to the application event queue where it will 
be processed asynchronously but before the next paint. There is a 
'workInQueue' flag to prevent flooding the queue with  workEvent events. It 
currently uses the default priority but this could change if necessary.

Neil

-- 
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/scintilla-interest/53a733dd-4541-44f4-bcfe-cc872ca5e231n%40googlegroups.com.

------=_Part_660257_1936559605.1785022728929
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

The other 3 included platforms try to perform styling before receiving pain=
t events so that paints do not attempt to work on incomplete style informat=
ion. The QueueIdleWork virtual method allows platform layers to schedule st=
yling although each platform does this a bit differently.<div><br /></div><=
div>The Qt platform layer does not currently implement QueueIdleWork so may=
 have to perform styling inside paint. If this changes styles outside the p=
aint area, it can cause that paint to be abandoned and a whole window repai=
nt scheduled. This is inefficient and could lead to visual hitches.</div><d=
iv><br /></div><div>Attached is a proposal for implementing QueueIdleWork o=
n Qt as a custom event 'workEvent'. The implementation is closest to the Wi=
n32 platform layer, posting a single event to the application event queue w=
here it will be processed asynchronously but before the next paint. There i=
s a 'workInQueue' flag to prevent flooding the queue with=C2=A0

workEvent=C2=A0events. It currently uses the default priority but this coul=
d change if necessary.</div><div><br /></div><div>Neil</div><div><br /></di=
v>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;scintilla-interest&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]">=
[email protected]</a>.<br />
To view this discussion visit <a href=3D"https://groups.google.com/d/msgid/=
scintilla-interest/53a733dd-4541-44f4-bcfe-cc872ca5e231n%40googlegroups.com=
?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com/d/msgid/=
scintilla-interest/53a733dd-4541-44f4-bcfe-cc872ca5e231n%40googlegroups.com=
</a>.<br />

------=_Part_660257_1936559605.1785022728929--

------=_Part_660256_567089582.1785022728929
Content-Type: text/plain; charset=US-ASCII; name=workEvent3.patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=workEvent3.patch
X-Attachment-Id: 8c3ed748-ebcd-4e37-acb4-a856ae3d988b
Content-ID: <8c3ed748-ebcd-4e37-acb4-a856ae3d988b>

diff -r e08b538dd1bd qt/ScintillaEditBase/ScintillaQt.cpp
--- a/qt/ScintillaEditBase/ScintillaQt.cpp	Sat Jul 25 18:10:24 2026 +1000
+++ b/qt/ScintillaEditBase/ScintillaQt.cpp	Sun Jul 26 09:36:54 2026 +1000
@@ -527,6 +527,24 @@
 	return ChangeIdle(on);
 }
 
+void ScintillaQt::customEvent(QEvent* event)
+{
+	if (event->type() == workEvent) {
+		workInQueue = false;
+		Editor::IdleWork();
+	}
+	QObject::customEvent(event);
+}
+
+void ScintillaQt::QueueIdleWork(WorkItems items, Sci::Position upTo)
+{
+	Editor::QueueIdleWork(items, upTo);
+	if (!workInQueue) {
+		QCoreApplication::postEvent(this, new QEvent(workEvent));
+		workInQueue = true;
+	}
+}
+
 CharacterSet ScintillaQt::CharacterSetOfDocument() const
 {
 	return vs.styles[STYLE_DEFAULT].characterSet;
diff -r e08b538dd1bd qt/ScintillaEditBase/ScintillaQt.h
--- a/qt/ScintillaEditBase/ScintillaQt.h	Sat Jul 25 18:10:24 2026 +1000
+++ b/qt/ScintillaEditBase/ScintillaQt.h	Sun Jul 26 09:36:54 2026 +1000
@@ -78,6 +78,8 @@
 
 namespace Scintilla::Internal {
 
+constexpr QEvent::Type workEvent = QEvent::User;
+
 class ScintillaQt : public QObject, public ScintillaBase {
 	Q_OBJECT
 
@@ -136,6 +138,8 @@
 	void FineTickerCancel(TickReason reason) override;
 	bool ChangeIdle(bool on);
 	bool SetIdle(bool on) override;
+	bool workInQueue = false;
+	void QueueIdleWork(WorkItems items, Sci::Position upTo) override;
 	void SetMouseCapture(bool on) override;
 	bool HaveMouseCapture() override;
 	void StartDrag() override;
@@ -172,6 +176,7 @@
 	void DropUrls(const QMimeData *data);
 
 	void timerEvent(QTimerEvent *event) override;
+	void customEvent(QEvent* event) override;
 
 private:
 	QAbstractScrollArea *scrollArea;

------=_Part_660256_567089582.1785022728929--