Re: Decreasing seams in scaled windows
Neil <[email protected]> Sun, 24 May 2026 20:34:49 -0700 (PDT)
| Newsgroups | gmane.comp.lib.scintilla.devel |
|---|---|
| Message-ID | <[email protected]> |
------=_Part_208204_1285727470.1779680089082 Content-Type: multipart/alternative; boundary="----=_Part_208205_1740363535.1779680089082" ------=_Part_208205_1740363535.1779680089082 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable There were some more problems on current Wayland with the popups reporting= =20 a devicePixelRatioF of 2.0 when the system scale was 1.5 or 1.33. Its=20 possible this is an initialization issue with windows not knowing an=20 accurate scaling factor before they receive a set scale message. It was=20 fixed by using the devicePixelRatioF of the main Scintilla window in the=20 attached patch. Mitchell: I like the indicators that I see without the patch. Having multiple new=20 scale-specific indicators doesn=E2=80=99t sound ideal. It's more likely you will be able to replace Diagonal with a single new=20 DiagonalProportionalToDescender (or similar name) that implements a=20 particular style of scaling diagonals. If there are different opinions on= =20 the best technique to use then there could be more than one Diagonal*. A=20 constraint here is that downstream Windows projects have been scaling for 6= =20 years and shouldn't have their appearance modified in ways that they may=20 not like or want. I increased my margin width using your new patch, but the markers remained= =20 the same, small size. Do I need to implement some sort of client-side=20 scaling? It is likely you will have to perform some scaling yourself. I did run into a strange issue with a Scintilla view that is normally 1=20 line high is now 2 lines high. However, I set the height using the=20 SCI_TEXTHEIGHT, so I suspect Scintilla is reporting a new scaled height.=20 Either I have to divide by two, or Scintilla (or its Qt platform) needs to= =20 do another computation somewhere. I'm not sure. There are really two scales working in the code: graphics and= =20 windowing with window coordinates not being scaled. I would like some sort of control to disable scaling and keep the default= =20 drawing Scintilla Qt is doing on my Retina and 4K display (I assume macOS= =20 is doing 200% scaling for both). When I have time, I can enable scaling and= =20 then identify and report any issues I find, as I am now. Right now it feels= =20 like I=E2=80=99m going to run into a lot of small things over time rather t= han all=20 at once. I=E2=80=99d be more comfortable with the fallback to disable and k= eep the=20 current drawing. I have been working on this but scaling occurs in many places and the=20 'scaled' control property needs to be distributed and kept current. Neil --=20 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 e= mail to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/scintilla-i= nterest/c4101367-bd2c-4159-97f9-5b21b496912en%40googlegroups.com. ------=_Part_208205_1740363535.1779680089082 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable There were some more problems on current Wayland with the popups reporting = a=C2=A0devicePixelRatioF of 2.0 when the system scale was 1.5 or 1.33. Its = possible this is an initialization issue with windows not knowing an accura= te scaling factor before they receive a set scale message. It was fixed by = using the=C2=A0devicePixelRatioF=C2=A0of the main Scintilla window in the a= ttached patch.<br /><br /><div><div dir=3D"auto">Mitchell:</div><div dir=3D= "auto"><br /></div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-l= eft: 1px solid rgb(204, 204, 204); padding-left: 1ex;">I like the indicator= s that I see without the patch. Having multiple new scale-specific indicato= rs doesn=E2=80=99t sound ideal.</blockquote><div><br /></div><div>It's more= likely you will be able to replace Diagonal with a single new DiagonalProp= ortionalToDescender (or similar name) that implements a particular style of= scaling diagonals. If there are different opinions on the best technique t= o use then there could be more than one Diagonal*. A constraint here is tha= t downstream=C2=A0Windows projects have been scaling for 6 years and should= n't have their appearance modified in ways that they may not like or want.<= /div><div><br /></div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; borde= r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">I increased my ma= rgin width using your new patch, but the markers remained the same, small s= ize. Do I need to implement some sort of client-side scaling?</blockquote><= div><br /></div><div>It is likely you will have to perform some scaling you= rself.</div><div><br /></div><blockquote style=3D"margin: 0px 0px 0px 0.8ex= ; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">I did run = into a strange issue with a Scintilla view that is normally 1 line high is = now 2 lines high. However, I set the height using the SCI_TEXTHEIGHT, so I = suspect Scintilla is reporting a new scaled height. Either I have to divide= by two, or Scintilla (or its Qt platform) needs to do another computation = somewhere.</blockquote><div><br /></div><div>I'm not sure. There are really= two scales working in the code: graphics and windowing with window coordin= ates not being scaled.</div><div><br /></div><blockquote style=3D"margin: 0= px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: = 1ex;">I would like some sort of control to disable scaling and keep the def= ault drawing Scintilla Qt is doing on my Retina and 4K display (I assume ma= cOS is doing 200% scaling for both). When I have time, I can enable scaling= and then identify and report any issues I find, as I am now. Right now it = feels like I=E2=80=99m going to run into a lot of small things over time ra= ther than all at once. I=E2=80=99d be more comfortable with the fallback to= disable and keep the current drawing.</blockquote><div><br /></div><div>I = have been working on this but scaling occurs in many places and the 'scaled= ' control property needs to be distributed and kept current.</div><div><br = /></div><div>Neil</div></div> <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/c4101367-bd2c-4159-97f9-5b21b496912en%40googlegroups.com= ?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com/d/msgid/= scintilla-interest/c4101367-bd2c-4159-97f9-5b21b496912en%40googlegroups.com= </a>.<br /> ------=_Part_208205_1740363535.1779680089082-- ------=_Part_208204_1285727470.1779680089082 Content-Type: text/plain; charset=US-ASCII; name=QtScaleA.patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=QtScaleA.patch X-Attachment-Id: 6d617180-a9d1-4e24-aad6-70fd1fad39a6 Content-ID: <6d617180-a9d1-4e24-aad6-70fd1fad39a6> diff -r c105229352ea qt/ScintillaEditBase/PlatQt.cpp --- a/qt/ScintillaEditBase/PlatQt.cpp Sun May 24 21:24:48 2026 +1000 +++ b/qt/ScintillaEditBase/PlatQt.cpp Mon May 25 13:10:40 2026 +1000 @@ -229,6 +229,11 @@ return std::make_unique<SurfaceImpl>(width, height, mode); } +std::unique_ptr<Surface> SurfaceImpl_AllocatePixMap(int width, int height, SurfaceMode mode) +{ + return std::make_unique<SurfaceImpl>(width, height, mode); +} + void SurfaceImpl::SetMode(SurfaceMode mode_) { mode = mode_; @@ -309,7 +314,7 @@ int SurfaceImpl::DeviceHeightFont(int points) { - return points; + return points * device->devicePixelRatioF(); } void SurfaceImpl::LineDraw(Point start, Point end, Stroke stroke) @@ -796,6 +801,9 @@ painter->setRenderHint(QPainter::TextAntialiasing, true); painter->setRenderHint(QPainter::Antialiasing, true); + + const qreal scale = device->devicePixelRatioF(); + painter->scale(1.0 / scale, 1.0 / scale); } return painter; @@ -854,6 +862,8 @@ void Window::SetPositionRelative(PRectangle rc, const Window *relativeTo) { + const qreal scale = window(relativeTo->GetID())->devicePixelRatioF(); + rc = rc / scale; QPoint oPos = window(relativeTo->wid)->mapToGlobal(QPoint(0,0)); int ox = oPos.x(); int oy = oPos.y(); @@ -884,7 +894,9 @@ PRectangle Window::GetClientPosition() const { // The client position is the window position - return GetPosition(); + const qreal scale = wid ? window(wid)->devicePixelRatioF() : 1.0; + const PRectangle rc = GetPosition(); + return rc * scale; } void Window::Show(bool show) @@ -901,8 +913,15 @@ void Window::InvalidateRectangle(PRectangle rc) { - if (wid) - window(wid)->update(QRectFromPRect(rc)); + if (wid) { + //const qreal scale = window(wid)->devicePixelRatioF(); + // Avoids aliasing leaving a partial bottom pixel + //rc = rc / scale; + //rc.top -= 20; + //rc.bottom += 2; + //window(wid)->update(QRectFromPRect(rc)); + window(wid)->update(); + } } void Window::SetCursor(Cursor curs) @@ -999,6 +1018,7 @@ int visibleRows{5}; QMap<int,QPixmap> images; float imageScale{1.0}; + QWidget *owner = nullptr; }; ListBoxImpl::ListBoxImpl() noexcept = default; @@ -1012,6 +1032,7 @@ unicodeMode = unicodeMode_; QWidget *qparent = static_cast<QWidget *>(parent.GetID()); + owner = qparent; ListWidget *list = new ListWidget(qparent); #if defined(Q_OS_WIN) @@ -1054,7 +1075,11 @@ ListWidget *list = GetWidget(); const FontAndCharacterSet *pfacs = AsFontAndCharacterSet(font); if (pfacs && pfacs->pfont) { - list->setFont(*(pfacs->pfont)); + QFont fontDeScaled = *(pfacs->pfont); + const qreal scale = window(owner)->devicePixelRatioF(); + qreal pointSize = fontDeScaled.pointSizeF() / scale; + fontDeScaled.setPointSizeF(pointSize); + list->setFont(fontDeScaled); } } void ListBoxImpl::SetAverageCharWidth(int /*width*/) {} @@ -1084,7 +1109,8 @@ width += style->pixelMetric(QStyle::PM_ScrollBarExtent); } - return PRectangle(0, 0, width, height); + const qreal scale = window(wid)->devicePixelRatioF(); + return PRectangle(0, 0, width, height) * scale; } int ListBoxImpl::CaretFromEdge() { diff -r c105229352ea qt/ScintillaEditBase/PlatQt.h --- a/qt/ScintillaEditBase/PlatQt.h Sun May 24 21:24:48 2026 +1000 +++ b/qt/ScintillaEditBase/PlatQt.h Mon May 25 13:10:40 2026 +1000 @@ -164,6 +164,8 @@ QPainter *GetPainter(); }; +std::unique_ptr<Surface> SurfaceImpl_AllocatePixMap(int width, int height, SurfaceMode mode); + } #endif diff -r c105229352ea qt/ScintillaEditBase/ScintillaEditBase.cpp --- a/qt/ScintillaEditBase/ScintillaEditBase.cpp Sun May 24 21:24:48 2026 +1000 +++ b/qt/ScintillaEditBase/ScintillaEditBase.cpp Mon May 25 13:10:40 2026 +1000 @@ -127,6 +127,12 @@ } else if (event->type() == QEvent::Hide) { setMouseTracking(false); result = QAbstractScrollArea::event(event); +#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) + } else if (event->type() == QEvent::DevicePixelRatioChange) { + // Reset cached data + sqt->InvalidateStyleRedraw(); + result = QAbstractScrollArea::event(event); +#endif } else { result = QAbstractScrollArea::event(event); } @@ -318,7 +324,7 @@ void ScintillaEditBase::mousePressEvent(QMouseEvent *event) { - const Point pos = PointFromQPoint(event->pos()); + const Point pos = PointFromQPoint(event->pos()) * devicePixelRatioF(); emit buttonPressed(event); @@ -347,7 +353,8 @@ void ScintillaEditBase::mouseReleaseEvent(QMouseEvent *event) { - const QPoint point = event->pos(); + const QPoint point = event->pos() * devicePixelRatioF(); + if (event->button() == Qt::LeftButton) sqt->ButtonUpWithModifiers(PointFromQPoint(point), TimeOfEvent(time), ModifiersOfKeyboard()); @@ -367,7 +374,7 @@ void ScintillaEditBase::mouseMoveEvent(QMouseEvent *event) { - const Point pos = PointFromQPoint(event->pos()); + const Point pos = PointFromQPoint(event->pos()) * devicePixelRatioF(); const bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier; const bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier; diff -r c105229352ea qt/ScintillaEditBase/ScintillaQt.cpp --- a/qt/ScintillaEditBase/ScintillaQt.cpp Sun May 24 21:24:48 2026 +1000 +++ b/qt/ScintillaEditBase/ScintillaQt.cpp Mon May 25 13:10:40 2026 +1000 @@ -809,13 +809,22 @@ void ScintillaQt::PartialPaint(const PRectangle &rect) { - rcPaint = rect; + QWidget *widget = static_cast<QWidget *>(wMain.GetID()); + const qreal scale = widget->devicePixelRatioF(); + + rcPaint = rect * scale; paintState = PaintState::painting; PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); + // Create Bitmap of exactly window size then blit after Paint call + const int w = static_cast<int>(rcClient.Width() * scale); + const int h = static_cast<int>(rcClient.Height() * scale); + std::unique_ptr<Surface> surfPix = SurfaceImpl_AllocatePixMap(w, h, CurrentSurfaceMode()); + PRectangle rcScaled = PRectangle::FromInts(0,0,w,h); + Paint(surfPix.get(), rcScaled); AutoSurface surfacePaint(this); - Paint(surfacePaint, rcPaint); + surfacePaint->Copy(rcScaled, Point(0,0), *surfPix); surfacePaint->Release(); if (paintState == PaintState::abandoned) { diff -r c105229352ea src/Geometry.h --- a/src/Geometry.h Sun May 24 21:24:48 2026 +1000 +++ b/src/Geometry.h Mon May 25 13:10:40 2026 +1000 @@ -45,6 +45,10 @@ return Point(x - other.x, y - other.y); } + constexpr Point operator*(XYPOSITION multiplier) const noexcept { + return Point(x * multiplier, y * multiplier); + } + // Other automatically defined methods (assignment, copy constructor, destructor) are fine }; @@ -101,6 +105,15 @@ return (rc.left == left) && (rc.right == right) && (rc.top == top) && (rc.bottom == bottom); } + + constexpr PRectangle operator*(XYPOSITION multiplier) const noexcept { + return PRectangle(left * multiplier, top * multiplier, right * multiplier, bottom * multiplier); + } + + constexpr PRectangle operator/(XYPOSITION divisor) const noexcept { + return PRectangle(left / divisor, top / divisor, right / divisor, bottom / divisor); + } + constexpr bool Contains(Point pt) const noexcept { return (pt.x >= left) && (pt.x <= right) && (pt.y >= top) && (pt.y <= bottom); ------=_Part_208204_1285727470.1779680089082--