Menu

#2503 Invalidate render targets when detecting a changed scaling factor

Bug
closed-fixed
nobody
5
2026-04-29
2026-03-30
No

This bug report is related to #2344 DirectWrite rendering looks blurry with DPI unaware apps.

When the application window which hosts Scintilla is moved to another monitor and the scaling factor of that monitor differs from the previous one, render targets need to be invalidated so that a call to ScintillaWin::EnsureRenderTarget() will drop the existing render target and recreate it with the scaling factor of the new monitor.

Therefore I suggest to alter the bottom section of ScintillaWin::UpdateRenderingParams() the following way:

const float newDeviceScaleFactor = Internal::GetDeviceScaleFactorWhenGdiScalingActive(hRootWnd);
if (deviceScaleFactor != newDeviceScaleFactor) {
    deviceScaleFactor = newDeviceScaleFactor;
    targets.valid = false;
}

When the application moves to another monitor with another scaling factor, a GDI scaling application will not inform child windows about WM_SIZE as its logical units aren't changing.

Discussion

  • Markus Nißl

    Markus Nißl - 2026-03-31

    Update: Yesterday, I was moving the application between monitors with the shortcut Win+Shift+Left/Right. This triggers the message WM_WINDOWPOSCHANGED.

    Alas, when you drag the application with the mouse between monitors, WM_WINDOWPOSCHANGED is not sent.

    The change in scale factor when crossing monitor boundaries does trigger WM_PAINT, but also WM_NCPAINT which is sent way less often than WM_PAINT. Hence I suggest to update ScintillaWin::WndProc() by moving the WM_NCPAINT case down to WM_WINDOWPOSCHANGED.

    Moreover, the reverseArrowCursor also needs to be invalidated.

            case WM_NCPAINT:
            case WM_WINDOWPOSCHANGED:
    #if defined(USE_D2D)
                if (technology != Technology::Default) {
                    if (UpdateRenderingParams(false)) {
                        reverseArrowCursor.Invalidate();
                        DropGraphics();
                        Redraw();
                    }
                }
    #endif
    
     
  • Neil Hodgson

    Neil Hodgson - 2026-04-08

    WM_NCPAINT doesn't appear to occur when the Scintilla window has no border as may be caused when any borders or dividers are supplied by other windows in the hierarchy.

     
    • Markus Nißl

      Markus Nißl - 2026-04-14

      The Scintilla edit control has no WS_BORDER style, though WM_NCPAINT is triggered.

       
  • Zufu Liu

    Zufu Liu - 2026-04-11
    • labels: Scintilla, Windows --> Scintilla, Windows, DirectWrite
     
  • Neil Hodgson

    Neil Hodgson - 2026-04-22

    Committed with [0c8e25].

     

    Related

    Commit: [0c8e25]

    • Markus Nißl

      Markus Nißl - 2026-04-22

      In your commit, you missed to also invalidate the reverse arrow cursor when handling WM_NCPAINTand WM_WINDOWPOSCHANGED in case UpdateRenderingParams(false) returns true:

      reverseArrowCursor.Invalidate();
      
       
      • Neil Hodgson

        Neil Hodgson - 2026-04-22
         

        Related

        Commit: [699a85]

  • Neil Hodgson

    Neil Hodgson - 2026-04-22
    • status: open --> open-fixed
     
  • Neil Hodgson

    Neil Hodgson - 2026-04-29
    • status: open-fixed --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB