Skip to content

Detect external file modifications immediately, matching Notepad++ behavior - #1122

Open
PCCV wants to merge 1 commit into
dail8859:masterfrom
PCCV:external-file-watcher
Open

Detect external file modifications immediately, matching Notepad++ behavior#1122
PCCV wants to merge 1 commit into
dail8859:masterfrom
PCCV:external-file-watcher

Conversation

@PCCV

@PCCV PCCV commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Description:

Closes #558.

Currently, NotepadNext only detects that a file was modified by another program when the tab is activated or the window regains focus (checkFileForModification() called only from activateEditor() and focusIn()). This means changes made externally can go unnoticed for a long time if the user stays on the same tab with the window in the background.

This PR adds a centralized QFileSystemWatcher in EditorManager to detect external modifications immediately, without waiting for a tab switch or focus change — matching Notepad++'s behavior.

Changes

  • EditorManager: single shared QFileSystemWatcher (rather than one per editor, to conserve file descriptors as discussed in Use QFileSystemWatcher for opened Editors #558). Watches/unwatches paths on editorCreated, closed, and renamed (the latter also covers Save As and New→File transitions). A 250ms debounce via QTimer::singleShot absorbs the double-signal behavior common to inotify-based watchers. New signal editorFileChangedOnDisk(ScintillaNext*).
  • MainWindow: connects to the new signal, guarded by isActiveWindow() and editor == currentEditor() so the dialog only appears for the currently visible tab in the foreground window — same UX as before, just triggered sooner.
  • MainWindow::changeEvent(): new override reacting to QEvent::ActivationChange to reliably catch the "switch back to NotepadNext without changing tabs" case. The existing applicationStateChanged-based path doesn't reliably fire in this scenario under X11/Cinnamon; changeEvent is Qt's own cross-platform activation notification and closes that gap. Left the existing mechanism in place since checkFileForModification() is a no-op when nothing changed.
  • Reload confirmation dialog now warns explicitly when the current tab has unsaved changes, since immediate detection makes the unsaved-changes + external-modification conflict much easier to hit than before (previously it required a coincidental tab switch). Reloading still discards local changes; this PR only makes that risk visible rather than adding merge/backup logic, which is out of scope here.

Known limitation

QFileSystemWatcher stops watching a file if it's replaced via atomic rename (as some editors/tools do on save). A best-effort re-arm (addPath if the path dropped out of fileWatcher->files()) is included, but this hasn't been exhaustively tested against every external tool's save strategy.

Tested

  • External modification while tab active / window focused
  • External modification while tab active / window unfocused, then refocus without switching tabs
  • External modification while tab active / window unfocused, then refocus via tab switch
  • Rename, Save As
  • Delete/recreate
  • Unsaved local changes + external modification (dialog now warns before discarding)

…havior

- Add centralized QFileSystemWatcher in EditorManager to detect external
  file changes without waiting for tab switch or window focus
- Reliably trigger the check on window (re)activation via
  QEvent::ActivationChange (covers X11/Cinnamon gap in existing
  applicationStateChanged mechanism)
- Warn the user before discarding unsaved changes when reloading a
  file modified externally
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use QFileSystemWatcher for opened Editors

1 participant