From 5c10bcc7ef9ca881b7d6d851992702bae53ff968 Mon Sep 17 00:00:00 2001 From: Zufu Liu Date: Thu, 18 Apr 2024 09:32:10 +1000 Subject: Bug [#2321]. Scale reverse arrow cursor for margins to match other cursors. --- doc/ScintillaHistory.html | 4 ++++ win32/PlatWin.cxx | 13 ++++++++++--- win32/PlatWin.h | 3 ++- win32/Scintilla.vcxproj | 2 +- win32/ScintillaWin.cxx | 25 +++++++++++++++++++++---- win32/makefile | 2 +- win32/scintilla.mak | 2 +- 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 5c711c199..94e2d285f 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -603,6 +603,10 @@ Fix Win32 IME crash in windowed mode. Bug #2433. +
  • + Scale reverse arrow cursor for margins to match other cursors when user changes pointer size. + Bug #2321. +
  • Release 5.4.3 diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 91194c4c5..c3c6b609a 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -2782,7 +2782,7 @@ void Window::InvalidateRectangle(PRectangle rc) { ::InvalidateRect(HwndFromWindowID(wid), &rcw, FALSE); } -HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept { +HCURSOR LoadReverseArrowCursor(UINT dpi, int cursorBaseSize) noexcept { class CursorHelper { public: ICONINFO info{}; @@ -2848,8 +2848,15 @@ HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept { HCURSOR reverseArrowCursor {}; - 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, USER_DEFAULT_SCREEN_DPI); + height = width; + } else { + width = SystemMetricsForDpi(SM_CXCURSOR, dpi); + height = SystemMetricsForDpi(SM_CYCURSOR, dpi); + } DPI_AWARENESS_CONTEXT oldContext = nullptr; if (fnAreDpiAwarenessContextsEqual && fnAreDpiAwarenessContextsEqual(fnGetThreadDpiAwarenessContext(), DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED)) { diff --git a/win32/PlatWin.h b/win32/PlatWin.h index f010923f2..70721d4a7 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -50,7 +50,8 @@ float GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept; int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept; -HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept; +constexpr int defaultCursorBaseSize = 32; +HCURSOR LoadReverseArrowCursor(UINT dpi, int cursorBaseSize) noexcept; class MouseWheelDelta { int wheelDelta = 0; diff --git a/win32/Scintilla.vcxproj b/win32/Scintilla.vcxproj index 4e4024234..3a416b053 100644 --- a/win32/Scintilla.vcxproj +++ b/win32/Scintilla.vcxproj @@ -95,7 +95,7 @@ Windows true - gdi32.lib;imm32.lib;ole32.lib;oleaut32.lib;%(AdditionalDependencies) + gdi32.lib;imm32.lib;ole32.lib;oleaut32.lib;advapi32.lib;%(AdditionalDependencies) diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index c6733469c..5e2532c84 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -294,6 +294,7 @@ class GlobalMemory; class ReverseArrowCursor { UINT dpi = USER_DEFAULT_SCREEN_DPI; + UINT cursorBaseSize = defaultCursorBaseSize; HCURSOR cursor {}; public: @@ -309,16 +310,17 @@ public: } } - HCURSOR Load(UINT dpi_) noexcept { + HCURSOR Load(UINT dpi_, UINT cursorBaseSize_) noexcept { if (cursor) { - if (dpi == dpi_) { + if (dpi == dpi_ && cursorBaseSize == cursorBaseSize_) { return cursor; } ::DestroyCursor(cursor); } dpi = dpi_; - cursor = LoadReverseArrowCursor(dpi_); + cursorBaseSize = cursorBaseSize_; + cursor = LoadReverseArrowCursor(dpi_, cursorBaseSize_); return cursor ? cursor : ::LoadCursor({}, IDC_ARROW); } }; @@ -359,6 +361,7 @@ class ScintillaWin : MouseWheelDelta horizontalWheelDelta; UINT dpi = USER_DEFAULT_SCREEN_DPI; + UINT cursorBaseSize = defaultCursorBaseSize; ReverseArrowCursor reverseArrowCursor; PRectangle rectangleClient; @@ -791,7 +794,7 @@ void ScintillaWin::DisplayCursor(Window::Cursor c) { c = static_cast(cursorMode); } if (c == Window::Cursor::reverseArrow) { - ::SetCursor(reverseArrowCursor.Load(static_cast(dpi * deviceScaleFactor))); + ::SetCursor(reverseArrowCursor.Load(static_cast(dpi * deviceScaleFactor), cursorBaseSize)); } else { wMain.SetCursor(c); } @@ -3220,6 +3223,20 @@ void ScintillaWin::GetMouseParameters() noexcept { charsPerScroll = (linesPerScroll == WHEEL_PAGESCROLL) ? 3 : linesPerScroll; } ::SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &typingWithoutCursor, 0); + + // https://learn.microsoft.com/en-us/answers/questions/815036/windows-cursor-size + HKEY hKey; + LSTATUS status = ::RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Cursors", 0, KEY_READ, &hKey); + if (status == ERROR_SUCCESS) { + DWORD baseSize = 0; + DWORD type = REG_DWORD; + DWORD size = sizeof(DWORD); + status = ::RegQueryValueExW(hKey, L"CursorBaseSize", nullptr, &type, reinterpret_cast(&baseSize), &size); + if (status == ERROR_SUCCESS && type == REG_DWORD) { + cursorBaseSize = baseSize; + } + ::RegCloseKey(hKey); + } } void ScintillaWin::CopyToGlobal(GlobalMemory &gmUnicode, const SelectionText &selectedText) { diff --git a/win32/makefile b/win32/makefile index 0ef6b23af..1760537c5 100644 --- a/win32/makefile +++ b/win32/makefile @@ -45,7 +45,7 @@ vpath %.h ../src ../include vpath %.cxx ../src LDFLAGS=-shared -static -mwindows -LIBS=-lgdi32 -luser32 -limm32 -lole32 -luuid -loleaut32 $(LIBSMINGW) +LIBS=-lgdi32 -luser32 -limm32 -lole32 -luuid -loleaut32 -ladvapi32 $(LIBSMINGW) INCLUDES=-I ../include -I ../src diff --git a/win32/scintilla.mak b/win32/scintilla.mak index 995e122d3..5034c8d0d 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -42,7 +42,7 @@ CXXNDEBUG=-O2 -MT -DNDEBUG -GL NAME=-Fo LDFLAGS=-OPT:REF -LTCG -IGNORE:4197 -DEBUG $(SUBSYSTEM) $(CETCOMPAT) LDDEBUG= -LIBS=KERNEL32.lib USER32.lib GDI32.lib IMM32.lib OLE32.lib OLEAUT32.lib +LIBS=KERNEL32.lib USER32.lib GDI32.lib IMM32.lib OLE32.lib OLEAUT32.lib ADVAPI32.lib NOLOGO=-nologo !IFDEF QUIET -- cgit v1.2.3