PasteBoard: defer minimize on /B + /I startup so auto-pasted clipboard is visible briefly

This commit is contained in:
Rainer Kottenhoff 2026-04-24 12:29:18 +02:00
parent f43319173c
commit fe91c42816
6 changed files with 57 additions and 16 deletions

View File

@ -32,6 +32,7 @@ SettingsVersion=5
;PasteBoardSeparator= ;(-> <use current EOL>) {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

View File

@ -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.).

View File

@ -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))

View File

@ -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) {

View File

@ -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 ==============================================

View File

@ -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];