Menu

#2450 [Qt/PySide] Visible bounding boxes around some characters, words, lines, margins, and near caret

Bug
open
nobody
5
2026-03-04
2024-11-02
8day
No

I'm using Qt 6.7.3/PySide 6.7.3 on Windows 11 23H2 along with updated version of original ScintillaEditPy. I know that this is a custom build, but there really isn't anything that should get in the way, as all the communication happens behind the scenes, almost not involving Python. For what it's worth, I haven't seen anything like that in Qt 5.12.x/PySide 5.12.x and Scintilla 4.x.

This is most noticeable, and usually noticeable at all with certain combinations of Windows 11 dark/light theme and light/dark styles used in Scintilla: default light Scintilla style paired with dark Windows 11 theme, and custom dark Scintilla style paired with light Windows 11 theme. Considering that it's not noticeable with light Windows theme and default light Scintilla theme, my guess is that themeing support wasn't implemented and things simply "worked". Screenshots can be seen in the attachment.

I guess I could try checking this w/o involving Python/PySide, but I have a really bad understanding of C++ and so building an example may take a few days. Maybe someone else can confirm this bug?

4 Attachments

Related

Bugs: #2500

Discussion

  • Neil Hodgson

    Neil Hodgson - 2024-11-02

    There have been similar visuals before from buggy scaling code. This may be due to setting a scaling factor like 125% in the Windows Settings Display page. The horizontal lines that appear for every second text line particularly reinforce this.

    The lines may be displayed with coordinates scaled so that the vertical lines differ by a non -integral value like 10.5 with lines starting at y values [0, 10.5, 21, 31.5, 42, ...]. What may be occurring is that, for the light appearance, the background is painted black, then each line is painted. Where a line ends at a .5, then that bottom edge pixel is merged with the background black to produce 50% grey. Then the next line is painted and its top edge is at .5 so its top pixel is merged with the 50% grey to make 25% grey.

    For a similar example see the 5th image at [#2344].

    You should turn off scaling and see if this is the issue.

     

    Related

    Bugs: #2344

  • 8day

    8day - 2024-11-03

    I think you are right, because I did use 125% scaling, and these lines were changing with different zoom values, as well as the patterns were repeating at certain zoom values. I'll try this later.

     

    Last edit: 8day 2024-11-03
  • 8day

    8day - 2024-11-03

    Yes, you were right. With scaling disabled everything looks as it should.

     
  • Neil Hodgson

    Neil Hodgson - 2024-11-04

    This is an issue with the way that scaling is being implemented in this case, either by Windows or Qt which are trying to enable scaling for an application that does not handle it itself. By marking the application as DPI-aware, the underlying window size and scaling factor may be made visible to Scintilla which will then divide the window up into independent lines and avoid the visual artifacts. SciTE and Notepad++ are both DPI-aware and you can examine their source code. There may be Qt APIs that could enable DPI-awareness and help handling that.

     
  • 8day

    8day - 2025-02-17

    It's not a proper fix and doesn't work on all platforms (worked for me on Windows 11 24H2), as stated at https://doc.qt.io/qt-6/highdpi.html#environment-variable-reference, but you can set environment variable QT_ENABLE_HIGHDPI_SCALING to 0 for a quick fix.

    QT_ENABLE_HIGHDPI_SCALING Set to 0 to disable high-dpi scaling; effectively reverting to Qt 5 default behavior. Note that this has no effect on platforms such as Wayland or macOS - it does not disable any native high-DPI support. This variable is intended for testing purposes only, and we do not recommend setting it on a permanent basis.

    I have also tried solution based on qt.conf, but it didn't work for me. In case if someone will succed, it's based on changing high DPI properties of the executable. It seems that it's not enough to set the variable mentioned at https://doc.qt.io/qt-6/highdpi.html#configuring-windows, more like entire qt.conf must be recreated (once again, I'm using it for PySide6 on Windows).

     

    Last edit: 8day 2025-02-17
  • Neil Hodgson

    Neil Hodgson - 2025-02-17

    Some extra clearing may help. Add the following line to EditView.cxx inside EditView::PaintText before the '// Loop on visible lines' comment.

    surface->FillRectangle(rcTextArea, Fill(vsDraw.styles[StyleDefault].back));
    

    This may cause further issues but there could be an option to enable this.

     
  • 8day

    8day - 2025-02-17

    Thank you, it works. There's still a visible line in the margin, but it's not annoying.

    Judging by what you said, I don't think you have to add extra option. Both solutions aren't perfect and seeing as QT_ENABLE_HIGHDPI_SCALING won't be removed for at least another year, there's still time to look for something better.

     
  • 8day

    8day - 2025-02-18

    I think I may have found a solution for this bug.

    See https://doc.qt.io/qt-6/qguiapplication.html#setHighDpiScaleFactorRoundingPolicy. In case of Python/PySide it's as simple as QApplication.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.Floor) (or any other suitable value).

    I'm kind of ashamed that it was right under my nose: https://doc.qt.io/qt-6/highdpi.html.

     
  • 8day

    8day - 2025-02-20

    BTW, after reading your comment at https://groups.google.com/g/scintilla-interest/c/crtyfjTFcv0/m/7l8zkcewAAAJ I've remembered that QApplication::setHighDpiScaleFactorRoundingPolicy() (as well as QT_ENABLE_HIGHDPI_SCALING=0) fixed failure in a copy of scintilla/test/simpleTests.py which I've ported to PySide: self.assertEqual(self.ed.XOffset, scroll_width * 8) in TestScrolling.testLineScroll() reports AssertionError: 26 != 25.6 for original code, as well as your patch for EditView::PaintText, but it gets fixed with QApplication::setHighDpiScaleFactorRoundingPolicy().

    Here is the method I've mentioned:

    def testLineScroll(self):
        self.ed.GotoLine(0)
        self.ed.LineScroll(0, 3)
        self.assertEqual(self.ed.FirstVisibleLine, 3)
        self.ed.LineScroll(0, -2)
        self.assertEqual(self.ed.FirstVisibleLine, 1)
        self.assertEqual(self.ed.XOffset, 0)
        self.ed.LineScroll(10, 0)
        self.assertGreater(self.ed.XOffset, 0)
        scroll_width = float(self.ed.XOffset) / 10
        self.ed.LineScroll(-2, 0)
        self.assertEqual(self.ed.XOffset, scroll_width * 8)
    
     

    Last edit: 8day 2025-02-20
  • Neil Hodgson

    Neil Hodgson - 2026-02-11
    • labels: --> scintilla, qt, seam, scaling
     
  • Neil Hodgson

    Neil Hodgson - 2026-03-04

    There is some work on a change to decrease seams in this mailing list thread.

     

Log in to post a comment.

MongoDB Logo MongoDB