diff --git a/src/Dialogs.c b/src/Dialogs.c index 3ad6f7daf..56c09dc54 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -2786,13 +2786,6 @@ CASE_WM_CTLCOLOR_SET: case IDOK: { - if (FileWatching.MonitoringLog) { - FileWatching.MonitoringLog = false; // will be toggled in IDM_VIEW_CHASING_DOCTAIL - PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); - EndDialog(hwnd, IDOK); - break; - } - if (IsButtonChecked(hwnd, IDC_RADIO_BTN_A)) { s_FWM = FWM_DONT_CARE; } @@ -2829,6 +2822,12 @@ CASE_WM_CTLCOLOR_SET: } } } + + if (FileWatching.MonitoringLog) { + FileWatching.MonitoringLog = false; // will be toggled in IDM_VIEW_CHASING_DOCTAIL + PostWMCommand(Globals.hwndMain, IDM_VIEW_CHASING_DOCTAIL); + } + EndDialog(hwnd, IDOK); } break; diff --git a/src/Edit.c b/src/Edit.c index 98e850574..6fe57ac92 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -5435,7 +5435,7 @@ void EditJumpTo(DocLn iNewLine, DocPos iNewCol) // jump to end with line set to -1 if ((iNewLine < 0) || (iNewLine > iMaxLine)) { - SciCall_DocumentEnd(); + Sci_SetCaretScrollDocEnd(); return; } if (iNewLine == 0) { diff --git a/src/Helpers.c b/src/Helpers.c index 31178956f..5ac3e7323 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -569,17 +569,14 @@ void BackgroundWorker_Start(BackgroundWorker* worker, _beginthreadex_proc_type r ResetEvent(worker->eventCancel); // init should be 'not signaled' //~worker->workerThread = CreateThread(NULL, 0, routine, property, 0, NULL); // MD(d) dll uintptr_t const thread = _beginthreadex(NULL, 0, routine, property, 0, NULL); // MT(d) static - worker->workerThread = (thread != 0LL) ? (HANDLE)thread : INVALID_HANDLE_VALUE; + InterlockedExchangePointer(&(worker->workerThread), (thread != 0LL) ? (HANDLE)thread : INVALID_HANDLE_VALUE); } } -// inline void BackgroundWorker_End(BackgroundWorker* worker, unsigned int retcode); - -static void _BckgrdWrkr_Stop(BackgroundWorker* worker) -{ +void BackgroundWorker_Cancel(BackgroundWorker* worker) { if (worker) { SetEvent(worker->eventCancel); // signal - HANDLE const workerThread = worker->workerThread; + HANDLE const workerThread = InterlockedExchangePointer(&(worker->workerThread), INVALID_HANDLE_VALUE); if (IS_VALID_HANDLE(workerThread)) { // Optimize: MsgDispatch only in case of hwnd ? // DWORD const wait = SignalObjectAndWait(worker->eventCancel, workerThread, 100 /*INFINITE*/, FALSE); @@ -591,23 +588,17 @@ static void _BckgrdWrkr_Stop(BackgroundWorker* worker) } } CloseHandle(workerThread); - worker->workerThread = INVALID_HANDLE_VALUE; } } } -void BackgroundWorker_Cancel(BackgroundWorker* worker) { - if (worker) { - _BckgrdWrkr_Stop(worker); - ResetEvent(worker->eventCancel); - } -} +// inline void BackgroundWorker_End(BackgroundWorker* worker, unsigned int retcode); -void BackgroundWorker_Destroy(BackgroundWorker* worker) { +void BackgroundWorker_Destroy(BackgroundWorker* worker) +{ if (worker) { - _BckgrdWrkr_Stop(worker); - CloseHandle(worker->eventCancel); - worker->eventCancel = INVALID_HANDLE_VALUE; + BackgroundWorker_Cancel(worker); + CloseHandle(InterlockedExchangePointer(&(worker->eventCancel), INVALID_HANDLE_VALUE)); Path_Release(worker->hFilePath); worker->hFilePath = NULL; } diff --git a/src/Notepad3.c b/src/Notepad3.c index 431070df3..701ba73ee 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -698,10 +698,18 @@ static bool s_flagJumpTo = false; static FILE_WATCHING_MODE s_flagChangeNotify = FWM_NO_INIT; static bool s_flagQuietCreate = false; static bool s_flagLexerSpecified = false; -static bool s_flagAppIsClosing = false; static bool s_flagDisplayHelp = false; static int s_iCaretPolicyV = CARET_EVEN; + +//============================================================================== + +static volatile HANDLE s_hFlagAppIsClosing = INVALID_HANDLE_VALUE; +static __forceinline bool IsAppClosing() { + return (WaitForSingleObject(s_hFlagAppIsClosing, 0) == WAIT_OBJECT_0); +} + + //============================================================================== // static forward declarations @@ -1779,6 +1787,9 @@ bool InitWndClass(const HINSTANCE hInstance, LPCWSTR lpszWndClassName, LPCWSTR l // HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) { + // manual (not automatic) reset & initial state: not signaled (TRUE, FALSE) + s_hFlagAppIsClosing = CreateEvent(NULL, TRUE, FALSE, NULL); + // init w/o hwnd g_IniWinInfo = GetWinInfoByFlag(NULL, Globals.CmdLnFlag_WindowPos); @@ -2005,7 +2016,7 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) if (g_flagMatchText & 2) { if (!s_flagJumpTo) { - SciCall_DocumentEnd(); + Sci_SetCaretScrollDocEnd(); } EditFindPrev(Globals.hwndEdit, &s_FindReplaceData, false, false, false); } else { @@ -2064,7 +2075,7 @@ HWND InitInstance(const HINSTANCE hInstance, int nCmdShow) } } - if (s_flagAppIsClosing || Globals.CmdLnFlag_PrintFileAndLeave) { + if (Globals.CmdLnFlag_PrintFileAndLeave || IsAppClosing()) { CloseApplication(); } @@ -2091,10 +2102,15 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) break; case WM_CLOSE: + SetEvent(s_hFlagAppIsClosing); + InstallFileWatching(false); if (FileSave(FSF_Ask)) { - s_flagAppIsClosing = true; DestroyWindow(Globals.hwndMain); } + else { + ResetEvent(s_hFlagAppIsClosing); + InstallFileWatching(true); + } break; case WM_QUERYENDSESSION: @@ -3264,14 +3280,14 @@ LRESULT MsgEndSession(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (!bShutdownOK) { + // Terminate file watching + InstallFileWatching(false); + RestorePrevScreenPos(hwnd); // Terminate AutoSave AutoSaveStop(); - // Terminate file watching - InstallFileWatching(false); - DragAcceptFiles(hwnd, FALSE); // Terminate clipboard watching @@ -3298,7 +3314,10 @@ LRESULT MsgEndSession(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) assert(!IsIniFileCached()); - if (umsg == WM_DESTROY) { + if (WM_DESTROY == umsg) { + if (IS_VALID_HANDLE(s_hFlagAppIsClosing)) { + CloseHandle(s_hFlagAppIsClosing); + } PostQuitMessage(0); } @@ -3773,7 +3792,7 @@ LRESULT MsgCopyData(HWND hwnd, WPARAM wParam, LPARAM lParam) if (g_flagMatchText & 2) { if (!s_flagJumpTo) { - SciCall_DocumentEnd(); + Sci_SetCaretScrollDocEnd(); } EditFindPrev(Globals.hwndEdit, &s_FindReplaceData, false, false, false); } else { @@ -6233,7 +6252,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) _lastCaretPos = SciCall_GetCurrentPos(); _saveChgNotify = FileWatching.FileWatchingMode; FileWatching.FileWatchingMode = FWM_AUTORELOAD; - SciCall_SetEndAtLastLine(true); + SciCall_SetEndAtLastLine(false); // false(!) FileRevert(Paths.CurrentFile, true); SciCall_SetReadOnly(FileWatching.MonitoringLog); } @@ -9634,7 +9653,7 @@ static void ParseCmdLnOption(LPWSTR lp1, LPWSTR lp2, const size_t len) case L'U': if (*CharUpper(lp1 + 1) == L'C') { - s_flagAppIsClosing = true; + SetEvent(s_hFlagAppIsClosing); } else { Flags.bDoRelaunchElevated = true; @@ -11469,14 +11488,13 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) // the .LOG feature ... if (IsFileVarLogFile()) { - SciCall_DocumentEnd(); + Sci_SetCaretScrollDocEnd(); UndoTransActionBegin(); SciCall_NewLine(); SendWMCommand(Globals.hwndMain, IDM_EDIT_INSERT_SHORTDATE); SciCall_DocumentEnd(); SciCall_NewLine(); EndUndoTransAction(); - SciCall_ScrollToEnd(); } if (!bReloadFile) { @@ -11605,8 +11623,7 @@ bool FileRevert(const HPATHL hfile_pth, bool bIgnoreCmdLnEnc) } else { // watch document end - SciCall_DocumentEnd(); - SciCall_ScrollToEnd(); + Sci_SetCaretScrollDocEnd(); } } @@ -11663,7 +11680,7 @@ bool DoElevatedRelaunch(EditFileIOStatus* pFioStatus, bool bAutoSaveOnRelaunch) // ---------------------------------------------- WCHAR wchFlags[32] = { L'\0' }; - if (s_flagAppIsClosing) { + if (IsAppClosing()) { StringCchCat(wchFlags, COUNTOF(wchFlags), L"/UC "); } if (bAutoSaveOnRelaunch) { @@ -11910,7 +11927,7 @@ bool FileSave(FileSaveFlags fSaveFlags) } // if current file is settings/config file: ask to start - if (Flags.bSettingsFileSoftLocked && !s_flagAppIsClosing) { + if (Flags.bSettingsFileSoftLocked && !IsAppClosing()) { ///~ LoadSettings(); NOT all settings will be applied ... WCHAR tch[256] = { L'\0' }; if (Settings.SaveSettings) { LoadLngStringW(IDS_MUI_RELOADCFGSEX, tch, COUNTOF(tch)); } @@ -11935,7 +11952,7 @@ bool FileSave(FileSaveFlags fSaveFlags) if (DoElevatedRelaunch(&fioStatus, true)) { CloseApplication(); } else { - s_flagAppIsClosing = false; + ResetEvent(s_hFlagAppIsClosing); if (Settings.MuteMessageBeep) { InfoBoxLng(MB_ICONWARNING, NULL, IDS_MUI_ERR_SAVEFILE, currentFileName); } else { @@ -12536,6 +12553,8 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) UNREFERENCED_PARAMETER(wParam); UNREFERENCED_PARAMETER(lParam); + if (IsAppClosing()) { return TRUE; } + SET_FCT_GUARD(TRUE); DocPos const iCurPos = SciCall_GetCurrentPos(); @@ -12745,6 +12764,7 @@ void InstallFileWatching(const bool bInstall) { _hCurrFileHandle = INVALID_HANDLE_VALUE; } + // static init if (!IS_VALID_HANDLE(s_FileChgObsvrData.worker.eventCancel)) { BackgroundWorker_Init(&(s_FileChgObsvrData.worker), NULL, NULL); } diff --git a/src/SciCall.h b/src/SciCall.h index 20a26175d..1753348d2 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -791,8 +791,7 @@ DeclareSciCallR0(IsSelectionRectangle, SELECTIONISRECTANGLE, bool); // length of line w/o line-end chars (full use SciCall_LineLength() #define Sci_GetNetLineLength(line) (SciCall_GetLineEndPosition(line) - SciCall_PositionFromLine(line)) -#define Sci_GoToDocEnd() { SciCall_DocumentEnd(); SciCall_ScrollToEnd(); } -//~#define Sci_GetDocEndPosition() SciCall_GetTextLength() +//~define Sci_GetDocEndPosition() SciCall_GetTextLength() #define Sci_GetDocEndPosition() SciCall_PositionAfter(SciCall_GetTextLength() - 1) #define Sci_ClampAlpha(alpha) clampi((alpha), SC_ALPHA_TRANSPARENT, SC_ALPHA_OPAQUE) //~SC_ALPHA_NOALPHA @@ -812,13 +811,13 @@ inline DocPos Sci_GetRangeMaxLineLength(DocLn iBeginLine, DocLn iEndLine) } // respect VSlop settings -inline void Sci_GotoPosChooseCaret(const DocPos pos) +__forceinline void Sci_GotoPosChooseCaret(const DocPos pos) { SciCall_GotoPos(pos); SciCall_ChooseCaretX(); } -inline void Sci_ScrollChooseCaret() +__forceinline void Sci_ScrollChooseCaret() { SciCall_ScrollCaret(); SciCall_ChooseCaretX(); @@ -832,7 +831,7 @@ inline void Sci_ScrollToLine(const DocLn line) SciCall_ScrollRange(SciCall_GetLineEndPosition(line), SciCall_PositionFromLine(line)); } -inline void Sci_ScrollToCurrentLine() +__forceinline void Sci_ScrollToCurrentLine() { Sci_ScrollToLine(Sci_GetCurrentLineNumber()); } @@ -859,7 +858,14 @@ inline void Sci_ScrollSelectionToView() SciCall_ScrollRange(SciCall_GetAnchor(), SciCall_GetCurrentPos()); } -inline void Sci_RedrawScrollbars() +__forceinline void Sci_SetCaretScrollDocEnd() +{ + SciCall_DocumentEnd(); + //~SciCall_ScrollToEnd(); + SciCall_ScrollCaret(); // enforce visible slop policy +} + +__forceinline void Sci_RedrawScrollbars() { SciCall_SetHScrollbar(false); SciCall_SetHScrollbar(true); @@ -867,6 +873,7 @@ inline void Sci_RedrawScrollbars() SciCall_SetVScrollbar(true); } + // if iRangeEnd == -1 : apply style from iRangeStart to document end #define Sci_ColouriseAll() SciCall_Colourise(0, -1)