Menu

#2321 SciTE: Windows 10 - Mouse cursor changes its size

Bug
closed-fixed
nobody
5
2024-07-22
2022-03-17
Thomas
No

I am using Notepad++ which uses SciTE as internal editor.

There I reported an issue under Windows 10 related to the enlarged mouse cursor.

Steps to reproduce the issue:
Change the settings for the mouse cursor:
Windows-10-mouse-settings

This video shows the current behavior.

I would expect the only the form of the mouse cursor but not its size will change.

Version Info:

SciTE
Version 5.2.1   Scintilla:5.2.1   Lexilla:5.1.5
    Feb 24 2022 10:38:37
by Neil Hodgson.
1 Attachments

Related

Bugs: #2460
Feature Requests: #1484

Discussion

1 2 3 > >> (Page 1 of 3)
  • Neil Hodgson

    Neil Hodgson - 2022-03-17
    • labels: SciTE, scite, Scite, Windows10 --> SciTE, scite, Windows10, scintilla
     
  • Neil Hodgson

    Neil Hodgson - 2022-03-17

    The arrow and I-beam cursors are directly provided by the system. The reverse arrow is constructed from the system arrow cursor bitmap for a particular screen resolution.

    After changing the cursor size in Settings, the bitmap returned for the system arrow is still the same 32x32 pixel size so Scintilla doesn't see the magnification.

     
  • Thomas

    Thomas - 2022-04-04

    Thanks for investigating this.

    Just for my understanding...

    You rate this issue as bug within Windows, because the magnification of the mouse cursor is not correctly handle for the right mouse pointer.

    On the other hand WinMerge (Version 2.12.4) and PowerShell ISE handle the right hand mouse cursor better than SciTE... as the attached photos show.

     

    Last edit: Thomas 2022-04-04
    • Neil Hodgson

      Neil Hodgson - 2022-04-04

      You rate this issue as bug within Windows

      No, I am describing the behaviour of the Windows APIs called by Scintilla.

      There will be other approaches that would require more effort to implement. For example, Scintilla could include alternative cursor images as is done on macOS. That would then not match the chosen colour when the "Change pointer Colour" option is used. Changing pointer colour does currently work with Scintilla but requires a restart of the application.

      This is not a high priority for me so it will require someone else to contribute a fix.

       
  • Zufu Liu

    Zufu Liu - 2023-03-16

    Custom loaded cursor works, e.g. the settings is in effect when dragging items on Notepad2's "Schemes -> Favorite Schemes" dialog (which uses res\Copy.cur). we may need a reverse arrow cursor like macOS?

     
  • Zufu Liu

    Zufu Liu - 2024-04-14

    From https://learn.microsoft.com/en-us/answers/questions/815036/windows-cursor-size
    HKEY_CURRENT_USER\Control Panel\Cursors\CursorBaseSize cursor pixel value.
    HKEY_CURRENT_USER\SOFTWARE\Microsoft\Accessibility\CursorSize the value on the slider.

    Also need to handle WM_SETTINGCHANGE (put the code inside GetMouseParameters()?).

     
  • Zufu Liu

    Zufu Liu - 2024-04-14

    Draft patch that uses CursorBaseSize (CursorSize is not updated when receives WM_SETTINGCHANGE message).

     
    • Zufu Liu

      Zufu Liu - 2024-04-14
      - if (cursorBaseSize > 32 && cursorBaseSize > width || cursorBaseSize > height)
      + if (cursorBaseSize > 32 && (cursorBaseSize > width || cursorBaseSize > height))
      
       
  • Zufu Liu

    Zufu Liu - 2024-04-15

    Update cursor size calculation to (cursorBaseSize is DPI independent)

    -   const int width = SystemMetricsForDpi(SM_CXCURSOR, dpi);
    -   const int height = SystemMetricsForDpi(SM_CYCURSOR, dpi);
    +   int width;
    +   int height;
    +   if (cursorBaseSize > defaultCursorBaseSize) {
    +       width = MulDiv(cursorBaseSize, dpi, uSystemDPI);
    +       height = width;
    +   } else {
    +       width = SystemMetricsForDpi(SM_CXCURSOR, dpi);
    +       height = SystemMetricsForDpi(SM_CYCURSOR, dpi);
    +   }
    
     
  • Neil Hodgson

    Neil Hodgson - 2024-04-16

    This is better but it is still (on Windows 10) scaling up the 32x32 cursor making the result blocky even though there is a smooth high resolution cursor used for the standard arrow. It's also smaller - maybe 90% of the standard arrow.

    This is the first use of the registry directly in Scintilla and could be an audit concern as registry reading can be used to fingerprint devices and users. The cocoa platform recently removed [6a80fd] calls to the analogous NSUserDefaults API as Apple is requiring justification for that in privacy manifests. It can be committed (without the dead #if 0 path) but it's unfortunate there isn't a more tightly scoped API.

     

    Related

    Commit: [6a80fd]

  • Zufu Liu

    Zufu Liu - 2024-04-16

    there is a smooth high resolution cursor used for the standard arrow

    Need to figure out why CopyImage() not using nearby sized frame from the cursor file.

     
  • Zufu Liu

    Zufu Liu - 2024-04-17

    Updated width calculation to width = ::MulDiv(cursorBaseSize, dpi, USER_DEFAULT_SCREEN_DPI);.

    https://learn.microsoft.com/en-us/answers/questions/1315176/how-to-copy-system-cursors-properly?cid=kerryherger

    Don't known how to improve CopyImage(), tried SetThreadCursorCreationScaling() on Win11 still not work:

    // dumpbin /exports User32.Lib
    using SetThreadCursorCreationScalingSig = UINT (WINAPI *)(UINT dpi);
    HMODULE user32 = ::GetModuleHandleW(L"user32.dll");
    SetThreadCursorCreationScalingSig fnSetThreadCursorCreationScaling = DLLFunction<SetThreadCursorCreationScalingSig>(user32, MAKEINTRESOURCEA(2079));
    if (fnSetThreadCursorCreationScaling) {
        dpi = ::MulDiv(width, USER_DEFAULT_SCREEN_DPI, defaultCursorBaseSize);
        dpi = fnSetThreadCursorCreationScaling(dpi);
        cursor = static_cast<HCURSOR>(::LoadImage({}, IDC_ARROW, IMAGE_CURSOR, width, height, LR_SHARED));
        fnSetThreadCursorCreationScaling(dpi);
    }
    
     
  • Neil Hodgson

    Neil Hodgson - 2024-04-18
    • labels: SciTE, scite, Windows10, scintilla --> SciTE, scite, Windows10, scintilla, cursor
    • status: open --> open-fixed
     
  • Neil Hodgson

    Neil Hodgson - 2024-04-18

    Committed with minor edits as [08b654]. It's quite ugly at larger magnifications so likely some users will see the change as a bug.

     

    Related

    Commit: [08b654]

  • Zufu Liu

    Zufu Liu - 2024-04-19

    Finally find out how to improve CopyImage(): load current system cursor file with LR_LOADFROMFILE. Arrow key under Control Panel\Cursors is the cursor file path (with correct size and color).

    This full change for Notepad2 https://github.com/zufuliu/notepad2/commit/8671ed51f64de38b892364c4a9d521a57ea4aa9e

    CursorBaseSize-0419.diff contains following changes:
    1. Delayed CursorBaseSize query into LoadReverseArrowCursor() function, only mark reverseArrowCursor as invalid inside GetMouseParameters(), so we can respect cursor color change too. dpi field also removed from ReverseArrowCursor class.
    2. Added copy != cursor after CopyImage() call in case it returns original cursor (LR_COPYRETURNORG).
    3. Added default: for Window::SetCursor().

    Will add another patch for LR_LOADFROMFILE (for non-standard sized cursor, i.e. if (dpi != uSystemDPI || cursorBaseSize > defaultCursorBaseSize)) changes.

     
    • Zufu Liu

      Zufu Liu - 2024-04-19

      Moved link comment above defaultCursorBaseSize statement.

       
  • Neil Hodgson

    Neil Hodgson - 2024-04-19

    OK with CursorBaseSize-0419-2.diff but won't be including loading from file as that expands Scintilla's security/privacy boundary to include file system access. The added functionality isn't worth that.

     
    • Zufu Liu

      Zufu Liu - 2024-04-19

      It just HCURSOR load = static_cast<HCURSOR>(::LoadImage({}, path, IMAGE_CURSOR, width, height, LR_LOADFROMFILE));.
      could be added under a preprocessor, so downstream project can opt-in on their own behave?

      https://github.com/zufuliu/notepad2/blob/main/scintilla/win32/PlatWin.cxx#L2945

       
  • Neil Hodgson

    Neil Hodgson - 2024-04-19

    Adding code under a preprocessor switch leaves it vulnerable to build or distribution system attacks, similar to the XZ Utils backdoor.

     
    • Zufu Liu

      Zufu Liu - 2024-04-19

      OK, understand.
      Should we restrict cursorBaseSize value? something like:

      constexpr DWORD maxCursorBaseSize = 256; // 16*(1 + 15)
      
      ...
      
      baseSize &= ~15; // multiple of 16
      cursorBaseSize = std::min(baseSize, maxCursorBaseSize);
      
       
      • Neil Hodgson

        Neil Hodgson - 2024-04-19

        Seems reasonable to limit size. The settings control doesn't seem well thought out - an intermediate choice between 1 and 2 seems much more useful to me than settings above 4.

         
  • Zufu Liu

    Zufu Liu - 2024-04-19

    Patch with maxCursorBaseSize = 16*(1 + 4);.

     
    • Zufu Liu

      Zufu Liu - 2024-04-19

      Removed redundant Comparision:

      if (status == ERROR_SUCCESS && type == REG_DWORD) {
          // CursorBaseSize is multiple of 16
          cursorBaseSize = std::min(baseSize & ~15, maxCursorBaseSize);
      }
      
       
  • Neil Hodgson

    Neil Hodgson - 2024-04-19

    Adding a reverse-arrow cursor resource with a few sizes (32, 48, 64?) to win32\ScintRes.rc would produce better quality visuals. SciTE has cursor resource loading for tab dragging with IDC_DRAGDROP.

     
    • Zufu Liu

      Zufu Liu - 2024-04-19

      That's what Visual Studio, PowerShell ISE do, they don't respect mouse color settings.

      Here is the script I used to create cursors from PNGs, https://github.com/zufuliu/notepad2/blob/main/tools/ImageTool.py#L313

      I think it can be used to dump system default cursor (%SystemRoot%\cursors\aero_arrow.cur) and flip it to make reverse arrow cursor like the one in Visual Studio.

       
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.