From 4ce7fbfbbaf806d4f49496fd77c1635cde2670ba Mon Sep 17 00:00:00 2001 From: Brian Tabone Date: Sat, 23 May 2026 20:36:45 -0500 Subject: [PATCH 1/2] feat(host): report real dark-mode state to plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three plugin-host messages were hardcoded to light mode (NPPM_ISDARKMODEENABLED, NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR, NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR) and NPPN_DARKMODECHANGED was never emitted. ComparePlus consumes these to choose its diff-color palette, so its bright pastel backgrounds stayed put under dark mode and washed out the underlying text. - appearance.{h,mm}: extract isAppDarkMode() from applyAppearance(). - nppm_handler.mm: report real dark-mode state and matching default bg/fg colors (0x1E1E1E / 0xD4D4D4 — same values the editor paints). - app_delegate.mm: emit NPPN_DARKMODECHANGED from appearanceChanged: so plugins refresh their palettes when the system theme flips. - docs/compare-plus-host-inventory.md: mark NPPN_DARKMODECHANGED as emitted; note NPPN_WORDSTYLESUPDATED is still unfired (no host style-configurator UI to drive it, and ComparePlus handles it identically to NPPN_DARKMODECHANGED). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/compare-plus-host-inventory.md | 7 +++--- macos/platform/app_delegate.mm | 5 +++++ macos/platform/appearance.h | 1 + macos/platform/appearance.mm | 33 +++++++++++++++++------------ macos/platform/nppm_handler.mm | 22 +++++++++---------- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/docs/compare-plus-host-inventory.md b/docs/compare-plus-host-inventory.md index cf922599c22c..05c2b7086bcb 100644 --- a/docs/compare-plus-host-inventory.md +++ b/docs/compare-plus-host-inventory.md @@ -47,8 +47,8 @@ ComparePlus can continue, but there is no equivalent visible macOS UI surface ye | `NPPM_GETCURRENTCMDLINE` | Compare.cpp (checkCmdLine) | **IMPLEMENTED** (nppm_handler.mm, returns empty command line) | | `NPPM_GETCURRENTNATIVELANGENCODING` | NppHelpers.h | **IMPLEMENTED** (nppm_handler.mm, returns UTF-8) | | `NPPN_GLOBALMODIFIED` | Compare.cpp | **NOT EMITTED** | -| `NPPN_DARKMODECHANGED` | Compare.cpp | **NOT EMITTED** | -| `NPPN_WORDSTYLESUPDATED` | Compare.cpp | **NOT EMITTED** | +| `NPPN_DARKMODECHANGED` | Compare.cpp | **EMITTED** (app_delegate.mm `appearanceChanged:`) | +| `NPPN_WORDSTYLESUPDATED` | Compare.cpp | **NOT EMITTED** (no host style-configurator UI yet to drive it; ComparePlus handles it identically to `NPPN_DARKMODECHANGED`, so dark-mode toggles already refresh its colors) | ## Command Alias / Navigation Surface @@ -90,4 +90,5 @@ SETLINENUMBERWIDTHMODE, GETBOOKMARKID, GETNATIVELANGFILENAME, GETCURRENTCMDLINE, GETCURRENTNATIVELANGENCODING NPPN: NPPN_READY, NPPN_SHUTDOWN, NPPN_LANGCHANGED, NPPN_FILEBEFORECLOSE, NPPN_FILESAVED, -NPPN_FILEOPENED, NPPN_FILECLOSED, NPPN_BUFFERACTIVATED, NPPN_BEFORESHUTDOWN, NPPN_TBMODIFICATION +NPPN_FILEOPENED, NPPN_FILECLOSED, NPPN_BUFFERACTIVATED, NPPN_BEFORESHUTDOWN, NPPN_TBMODIFICATION, +NPPN_DARKMODECHANGED diff --git a/macos/platform/app_delegate.mm b/macos/platform/app_delegate.mm index 784181425e9f..7c23460eaa48 100644 --- a/macos/platform/app_delegate.mm +++ b/macos/platform/app_delegate.mm @@ -626,6 +626,11 @@ - (void)appearanceChanged:(NSNotification*)notification ScintillaBridge_sendMessage(ctx().scintillaView, SCI_COLOURISE, 0, -1); if (ctx().isSplit && ctx().scintillaView2) ScintillaBridge_sendMessage(ctx().scintillaView2, SCI_COLOURISE, 0, -1); + + SCNotification darkNotif{}; + darkNotif.nmhdr.hwndFrom = ctx().mainHwnd; + darkNotif.nmhdr.code = NPPN_DARKMODECHANGED; + pluginManager().notify(&darkNotif); }); } diff --git a/macos/platform/appearance.h b/macos/platform/appearance.h index 87d9d33862e2..135995aceaa4 100644 --- a/macos/platform/appearance.h +++ b/macos/platform/appearance.h @@ -3,6 +3,7 @@ #pragma once +bool isAppDarkMode(); void applyFoldMarkerColorsToView(void* sci, bool isDark); void applyAppearanceToView(void* sci, int langIdx, bool isDark); void applyAppearance(); diff --git a/macos/platform/appearance.mm b/macos/platform/appearance.mm index f8611b90de37..a64364eaddd0 100644 --- a/macos/platform/appearance.mm +++ b/macos/platform/appearance.mm @@ -5,14 +5,21 @@ #include "appearance.h" #include "npp_constants.h" #include "app_state.h" -#include "language_defs.h" -#include "lexer_styles.h" -#include "scintilla_config.h" -#include "scintilla_bridge.h" -#include "brace_match.h" -#include "smart_highlight.h" +#include "language_defs.h" +#include "lexer_styles.h" +#include "scintilla_config.h" +#include "scintilla_bridge.h" +#include "brace_match.h" +#include "smart_highlight.h" #include "change_history.h" +bool isAppDarkMode() +{ + NSAppearanceName appearanceName = [NSApp.effectiveAppearance + bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; + return [appearanceName isEqualToString:NSAppearanceNameDarkAqua]; +} + void applyFoldMarkerColorsToView(void* sci, bool isDark) { if (!sci) return; @@ -68,19 +75,17 @@ void applyAppearanceToView(void* sci, int langIdx, bool isDark) configureSmartHighlightIndicator(sci, isDark); // Incremental search indicator colors - ScintillaBridge_sendMessage(sci, SCI_INDICSETFORE, INDIC_INCREMENTAL_SEARCH, - isDark ? 0x50C8FF : 0xFF8000); - - refreshLineNumberMargin(sci); -} + ScintillaBridge_sendMessage(sci, SCI_INDICSETFORE, INDIC_INCREMENTAL_SEARCH, + isDark ? 0x50C8FF : 0xFF8000); + + refreshLineNumberMargin(sci); +} void applyAppearance() { if (!ctx().scintillaView) return; - NSAppearanceName appearanceName = [NSApp.effectiveAppearance - bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; - bool isDark = [appearanceName isEqualToString:NSAppearanceNameDarkAqua]; + bool isDark = isAppDarkMode(); int langIdx = 0; if (ctx().activeTab >= 0 && ctx().activeTab < static_cast(ctx().documents.size())) diff --git a/macos/platform/nppm_handler.mm b/macos/platform/nppm_handler.mm index 21451d887847..c416d26c2d6b 100644 --- a/macos/platform/nppm_handler.mm +++ b/macos/platform/nppm_handler.mm @@ -12,6 +12,7 @@ #include "menu_builder.h" #include "string_utils.h" #include "compare_plus_visibility.h" +#include "appearance.h" #include "Notepad_plus_msgs.h" #include "Scintilla.h" @@ -234,21 +235,20 @@ LRESULT handleNppmMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } case NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR: - // Returned as 0x00BBGGRR (Win32 COLORREF). White matches our - // default light-mode Scintilla background. Plugins derive - // dependent colors (ComparePlus's "blank" marker shade) from - // this; returning 0 / black made the whole diff wash read as - // near-black, hiding the actual marker colors. - // TODO Phase 5: dark-mode branch. - return 0x00FFFFFF; + // Returned as 0x00BBGGRR (Win32 COLORREF). Must match the + // Scintilla default-style background actually painted (see + // appearance.mm:33), or plugins derive marker shades against + // the wrong base — ComparePlus's "blank" marker in particular. + return isAppDarkMode() ? 0x001E1E1E : 0x00FFFFFF; case NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR: - return 0x00000000; + return isAppDarkMode() ? 0x00D4D4D4 : 0x00000000; case NPPM_ISDARKMODEENABLED: - // Until we wire up real dark-mode detection, report light mode. - // ComparePlus picks its color palette based on this. - return FALSE; + // ComparePlus picks its color palette based on this; on TRUE + // it switches to Settings.useDarkColors() so diff backgrounds + // stay legible against a dark editor background. + return isAppDarkMode() ? TRUE : FALSE; case NPPM_ALLOCATEMARKER: { From bcec1c801af923f864240c35c557b8f581c101ff Mon Sep 17 00:00:00 2001 From: Brian Tabone Date: Sat, 23 May 2026 20:43:56 -0500 Subject: [PATCH 2/2] review: reference SCI_STYLESETBACK by symbol, not line number The comment in NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR pointed at appearance.mm:33, but adding the isAppDarkMode() helper above shifted the actual call. Point at SCI_STYLESETBACK for style 32 inside applyAppearanceToView instead so the reference doesn't rot again. Co-Authored-By: Claude Opus 4.7 (1M context) --- macos/platform/nppm_handler.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/macos/platform/nppm_handler.mm b/macos/platform/nppm_handler.mm index c416d26c2d6b..6cad8e1f9afa 100644 --- a/macos/platform/nppm_handler.mm +++ b/macos/platform/nppm_handler.mm @@ -236,9 +236,10 @@ LRESULT handleNppmMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR: // Returned as 0x00BBGGRR (Win32 COLORREF). Must match the - // Scintilla default-style background actually painted (see - // appearance.mm:33), or plugins derive marker shades against - // the wrong base — ComparePlus's "blank" marker in particular. + // background Scintilla paints for style 32 in + // applyAppearanceToView (SCI_STYLESETBACK), or plugins derive + // marker shades against the wrong base — ComparePlus's "blank" + // marker in particular. return isAppDarkMode() ? 0x001E1E1E : 0x00FFFFFF; case NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR: