Skip to content

Conversation

@Cordtus
Copy link

@Cordtus Cordtus commented Dec 12, 2025

Problem

When using LazPaint with the Qt6 widgetset, users may experience sluggish rendering and UI glitches during editing or zooming operations.

Root Cause

The uimageview.pas file defines two rendering optimizations:

{$IF defined(LINUX) and not defined(LCLqt5)}{$DEFINE IMAGEVIEW_DIRECTUPDATE}{$ENDIF}
{$IF not defined(DARWIN) and not defined(LCLqt5)}{$DEFINE IMAGEVIEW_QUICKUPDATE}{$ENDIF}

These optimizations:

  • IMAGEVIEW_DIRECTUPDATE: Bypasses Qt's paint queue and renders directly
  • IMAGEVIEW_QUICKUPDATE: Forces immediate Update() after InvalidateRect()

The original code (from 2020, commit b80b767) correctly excluded Qt5 from these optimizations, but Qt6 was not yet supported by Lazarus at that time and was not excluded.

Why Qt5/Qt6 Need Different Handling

Qt's paint system expects all painting to go through paintEvent() handlers via the event loop. From Qt documentation:

update() does not cause an immediate repaint; instead it schedules a paint event for processing when Qt returns to the main event loop. This permits Qt to optimize for more speed and less flicker. Calling update() several times normally results in just one paintEvent() call.

Qt6 maintains the same event-driven paint model as Qt5. In fact, Qt6 went further by deprecating repaint() entirely, as synchronous painting "does not work well on modern systems."

The direct update patterns that work on GTK conflict with Qt's event coalescing and can cause:

  • Race conditions between paint events
  • Double-painting
  • Visual tearing and artifacts

Solution

Add and not defined(LCLqt6) to both conditional defines, matching the existing Qt5 exclusion:

{$IF defined(LINUX) and not defined(LCLqt5) and not defined(LCLqt6)}{$DEFINE IMAGEVIEW_DIRECTUPDATE}{$ENDIF}
{$IF not defined(DARWIN) and not defined(LCLqt5) and not defined(LCLqt6)}{$DEFINE IMAGEVIEW_QUICKUPDATE}{$ENDIF}

References

Testing

Built and verified application launches correctly on Arch Linux with Qt6Pas 6.2.9, FPC 3.2.2, Lazarus 3.8.

Qt6, like Qt5, requires all painting to go through the standard event
loop via paintEvent(). The IMAGEVIEW_DIRECTUPDATE and IMAGEVIEW_QUICKUPDATE
optimizations bypass this, causing sluggish rendering and UI glitches
when editing or zooming.

The original code excluded Qt5 but not Qt6, which was added to Lazarus
after this code was written (2020).

Qt documentation confirms Qt6 maintains the same paint model as Qt5,
with repaint() being deprecated in favor of update() for event-driven
painting.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant