From fe91c428168d66bde94947ce2235bca830d16b08 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Fri, 24 Apr 2026 12:29:18 +0200 Subject: [PATCH] PasteBoard: defer minimize on /B + /I startup so auto-pasted clipboard is visible briefly --- Build/Notepad3.ini | 1 + readme/config/Configuration.md | 4 +++ src/Config/Config.cpp | 1 + src/Notepad3.c | 65 +++++++++++++++++++++++++--------- src/Notepad3.h | 1 + src/TypeDefs.h | 1 + 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/Build/Notepad3.ini b/Build/Notepad3.ini index e80c4d5de..349f8e38e 100644 --- a/Build/Notepad3.ini +++ b/Build/Notepad3.ini @@ -32,6 +32,7 @@ SettingsVersion=5 ;PasteBoardSeparator= ;(-> ) {separator pre-pended before each new clipboard entry (pasted at caret) in pasteboard mode; suppressed on first paste after enable and when caret is at a line start; empty=no separator; supports \r\n, \n, \t, \xHH; include newlines explicitly e.g. "\r\n---\r\n" for a dashed separator line} ;PasteBoardDebounceMs=200 ;(min: 0, max: 5000[msec]) {debounce interval for clipboard monitoring} ;PasteBoardAddTimestamp=0 ;(0/1) {prepend [HH:MM:SS] timestamp to each pasted entry in pasteboard mode} +;PasteBoardInitialShowMs=1500 ;(min: 500, max: 5000[msec]) {when launched with /B and /I together: show the window normally for this duration so the auto-pasted clipboard is visible, then minimize. Has no effect unless both /B and /I are passed.} ;NoFadeHidden=0 ;NoFileVariables=0 ;NoHTMLGuess=0 diff --git a/readme/config/Configuration.md b/readme/config/Configuration.md index 7a2e2aaa4..aa99837bc 100644 --- a/readme/config/Configuration.md +++ b/readme/config/Configuration.md @@ -226,6 +226,10 @@ PasteBoardSeparator=\r\n\r\n\r\n ; two blank lines between entries Set to `1` to prepend a `[HH:MM:SS]` timestamp to each pasted entry. +#### `PasteBoardInitialShowMs=1500` + +When Notepad3 is launched with **both `/B` (clipboard monitoring) and `/I` (start minimized)**, the immediate minimize is deferred so the user can see the window populate with the one-shot auto-pasted clipboard content. The window stays visible for this many milliseconds, then minimizes (to the tray or taskbar, per `Settings.MinimizeToTray`). Range: `500`–`5000` ms (clamped at load time). Has no effect unless both `/B` and `/I` are passed on the command line — `/I` alone still minimizes immediately as before. + #### `NoFadeHidden=0` Set to `1` to disable fading of hidden objects in file lists (Favorites, etc.). diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index b4753bda6..3b6b8fccd 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -1480,6 +1480,7 @@ void LoadSettings() } Settings2.PasteBoardDebounceMs = clampi(IniSectionGetInt(IniSecSettings2, L"PasteBoardDebounceMs", 200), 0, 5000); Settings2.PasteBoardAddTimestamp = IniSectionGetBool(IniSecSettings2, L"PasteBoardAddTimestamp", false); + Settings2.PasteBoardInitialShowMs = clampi(IniSectionGetInt(IniSecSettings2, L"PasteBoardInitialShowMs", 1500), 500, 5000); for (int i = 0; i < COUNTOF(Settings2.CodeFontPrefPrioList); ++i) { if (i < COUNTOF(g_CodeFontPrioList)) diff --git a/src/Notepad3.c b/src/Notepad3.c index fb808f036..16a5933e7 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -1849,6 +1849,35 @@ bool InitWndClass(const HINSTANCE hInstance, LPCWSTR lpszWndClassName, LPCWSTR l #endif +//============================================================================= +// +// _StartupMinimizeMainWnd() / _DeferMinimizeTimerProc() +// Hoisted from InitInstance() so the same minimize sequence runs either immediately +// or after the deferred-minimize timer fires (used for the /B + /I startup combo). +// +static void _StartupMinimizeMainWnd(HWND hwndMain) +{ + SetWindowPos(hwndMain, Settings.AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + if (!Settings.ShowTitlebar) { + SetWindowLong(hwndMain, GWL_STYLE, GetWindowLong(hwndMain, GWL_STYLE) & ~WS_CAPTION); + } + if (Settings.MinimizeToTray) { + MinimizeWndToTray(hwndMain); + } + else { + MinimizeWndToTaskbar(hwndMain); + } +} + +static VOID CALLBACK _DeferMinimizeTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + UNREFERENCED_PARAMETER(uMsg); + UNREFERENCED_PARAMETER(dwTime); + KillTimer(hwnd, idEvent); // one-shot + _StartupMinimizeMainWnd(hwnd); +} + + //============================================================================= // // InitInstance() - DarkMode already initialized ! @@ -1930,15 +1959,21 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) // Determine if starting minimized/tray (don't show window early in that case) bool const bStartMinimized = s_flagStartAsTrayIcon || (nCmdShow == SW_MINIMIZE) || (nCmdShow == SW_SHOWMINIMIZED); + // /B + /I together: show the window long enough for the one-shot auto-paste to land, + // then minimize via timer (fired below after PasteBoard_Start). Captures s_flagPasteBoard + // before the PasteBoard activation block clears it. + bool const bDeferMinimizeForPasteBoard = bStartMinimized && s_flagPasteBoard; // Show window frame early for faster perceived startup — the user sees - // the window (with initial toolbar from WM_CREATE) while we re-create bars - if (!bStartMinimized) { + // the window (with initial toolbar from WM_CREATE) while we re-create bars. + // For the /B + /I deferred-minimize case, force SW_SHOWNORMAL: nCmdShow could be + // SW_SHOWMINIMIZED (shortcut "Start minimized") which would defeat the purpose. + if (!bStartMinimized || bDeferMinimizeForPasteBoard) { if (!Settings.ShowTitlebar) { SetWindowLong(hwndMain, GWL_STYLE, GetWindowLong(hwndMain, GWL_STYLE) & ~WS_CAPTION); } SetWindowPos(hwndMain, Settings.AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(hwndMain, nCmdShow); + ShowWindow(hwndMain, bDeferMinimizeForPasteBoard ? SW_SHOWNORMAL : nCmdShow); UpdateWindow(hwndMain); } @@ -1949,7 +1984,7 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) // Force layout recalculation after toolbar/statusbar re-creation // (early ShowWindow already triggered WM_SIZE with old child windows) - if (!bStartMinimized) { + if (!bStartMinimized || bDeferMinimizeForPasteBoard) { RECT rc; GetClientRect(hwndMain, &rc); SendMessage(hwndMain, WM_SIZE, SIZE_RESTORED, MAKELPARAM(rc.right, rc.bottom)); @@ -2010,21 +2045,13 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) ShowWindowAsync(s_hwndEditFrame, SW_SHOWDEFAULT); ShowWindowAsync(Globals.hwndEdit, SW_SHOWDEFAULT); - if (bStartMinimized) { + if (bStartMinimized && !bDeferMinimizeForPasteBoard) { //~SnapToWinInfoPos(hwndMain, g_IniWinInfo, SCR_NORMAL, SW_HIDE); - SetWindowPos(hwndMain, Settings.AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - if (!Settings.ShowTitlebar) { - SetWindowLong(hwndMain, GWL_STYLE, GetWindowLong(hwndMain, GWL_STYLE) & ~WS_CAPTION); - } - if (Settings.MinimizeToTray) { - MinimizeWndToTray(hwndMain); - } - else { - MinimizeWndToTaskbar(hwndMain); - } + _StartupMinimizeMainWnd(hwndMain); } else { - // Window was already shown above; ensure children are painted + // Either not minimizing, or deferring minimize until /B auto-paste lands — + // the window must paint normally so the user sees the pasted content briefly. UpdateWindow(hwndMain); } @@ -2186,6 +2213,12 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) } } + // /B + /I: arm the deferred-minimize timer now that PasteBoard is started. + // PasteBoardInitialShowMs is clamped to 500..5000 at load time. + if (bDeferMinimizeForPasteBoard) { + SetTimer(Globals.hwndMain, ID_DEFERMINIMIZETIMER, (UINT)Settings2.PasteBoardInitialShowMs, _DeferMinimizeTimerProc); + } + // check if a lexer was specified from the command line if (s_flagLexerSpecified) { if (s_lpSchemeArg) { diff --git a/src/Notepad3.h b/src/Notepad3.h index 28932943a..1dbba8887 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -70,6 +70,7 @@ np3params, *LPnp3params; #define ID_LOGROTATETIMER (0xA003) // Log Rotation Retry #define ID_AUTOSCROLLTIMER (0xA004) // Middle-Click Auto-Scroll #define ID_ATOMICSAVETIMER (0xA005) // Atomic Save Detection +#define ID_DEFERMINIMIZETIMER (0xA006) // Deferred minimize on /B + /I startup //==== Reuse Window Lock Timeout ============================================== diff --git a/src/TypeDefs.h b/src/TypeDefs.h index 22d3057f9..a81715e87 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -878,6 +878,7 @@ typedef struct SETTINGS2_T { WCHAR PasteBoardSeparator[MICRO_BUFFER]; int PasteBoardDebounceMs; bool PasteBoardAddTimestamp; + int PasteBoardInitialShowMs; const WCHAR* CodeFontPrefPrioList[MICRO_BUFFER]; const WCHAR* TextFontPrefPrioList[MICRO_BUFFER];