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" 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--