1. At [line 3747 of document.c](https://github.com/geany/geany/blob/e5680fe85de536fc61ff0f2d4eadc54171d6c982...) the value of `doc->priv->file_disk_status` is set to `FILE_OK` **immediately after it was set to** `FILE_CHANGED`. This seems a bug, possible this glitch was earlier mentioned in the [comments here](https://github.com/geany/geany/pull/1180). This information is needed to implement [reload all](https://github.com/geany/geany/issues/2540), but disappears too early. (A similar field `doc->changed` nicely updates only when the text buffer is updated. It has another purpose, I know)
2. Studying the behavior in some more detail I wonder this enumeration type can be simplified: ```C typedef enum { FILE_OK, FILE_CHANGED, /* also valid for deleted files */ /* FILE_IGNORE --> Not needed anymore? */ } FileDiskStatus; ```
The `FILE_CHANGED` value is only used by the GIO file monitoring code AFAICT. That is never enabled because it has issues with multiple triggering (possibly due to the documented erorrs and incompletnes of inotify(7)) but its left there in case "somebody" figures it out and fixes it. If not at some point it will have decayed too far and should be removed. IIRC it needed the extra flag value because it used the infobar so the status had to persist.
Reading the documentation on the man page, I assume that using the mask `IN_ONESHOT` may solve a problem that possibly arises: when a file is saved, it is actually modified again, which triggers another event. This recursion presumably happens even apart from all possible race conditions in threads. The `FileDiskStatus` type may become handy to distinguish the items with and without buffered data in [Reload all](https://github.com/geany/geany/issues/2540) feature request. Will study that further.
Remember I said "possibly", GIO may also use plain polling just like Geany does, also not helping its determinism ;-). And even if it uses `inotify` Geany has no way to control the flags GIO uses. And of course it must use something else on Windows, not sure about Macos. These portability issues are why Geany tried to use GIO, not inotify or anything else, just a pity it doesn't work well enough for the purpose.
Perhaps you should outline your algorithm before you go implementing it. I don't see why you need another flag?
You have `doc->changed` to tell you the buffer state, and `document_check_disk_status()` to check the file status, so iterate the open documents and make a list of those that are changed on disk and note which have changed buffers. AFAICT thats all you need to implement reload all as discussed [here](https://github.com/geany/geany/issues/2540#issuecomment-1774779482).
But also note that `document_check_disk_status()` won't check files it thinks are remote, although I didn't check how it finds that out and how well it works.
The function `document_check_disk_status()` must be disentangled for a [Reload all](https://github.com/geany/geany/issues/2540) feature as first **all** file modifications have to be examined before **any** correct display warning can be created.
Furthermore, I interpret the value of `doc->changed` as a modification of the text buffer in RAM, and `doc->priv->file_disk_status` as the interpretation of the disk on file. A modification of the file on disk should not set `doc->changed` to TRUE, as we may still close the application without losing data. Some work in progress is visible [here](https://github.com/peter-scholtens/geany/tree/re-load-all). Known issues: 1. GUI is messy, but already report other files, just to get the idea. 2. GUI always has five buttons, but the amount of unmodified files or others may be zero. 3. Response of `RESPONSE_DOCUMENT_RELOAD_ALL` is not finished.
As you said [here](https://github.com/geany/geany/issues/2540#issuecomment-1774779482), you want to make two lists:
Just to be clear about something, the _document_ is the in memory object, the _file_ is the thing on disk.
For open documents where the file has changed on disk, you want a list where the document has unsaved changes, and a list where it does not, lets call them `unsaved list` and `unchanged list`.
AFAICT the algorithm to do that is simply:
``` for d in all open documents if document_check_disk_status(d) if d->changed add d to the unsaved list else add d to unchanged list ```
You MUST call `document_check_disk_status()` for all open documents to get up to date status, do not try to use existing monitoring states, they are created by a timer, so you have no idea how old they are and they may not reflect the current file state. But `doc->changed` is the correct thing to indicate the document has been modified.
Then if the either list is not empty go to the GUI and show the lists, its fine if one is empty, but do not go to the GUI if there is nothing to reload. If the response is `cancel` then do nothing, if the response is `reload only unchanged` then iterate the `unchanged list` only and reload those documents, if the response is `reload all` then iterate both lists and reload those documents, if the response is `overwrite all` then iterate both lists and save the buffers (I guess thats what you meant by "overwrite", maybe that needs more discussion if its a good idea).
As end user I want to see all relevant data at once, as the typical use case is that either a revision control tool (or untar, unzip,...) is modifying a lot of files at ones. Therefore I created `document_check_disk_status_others(.., gboolean force)` which can be called when re-entering the application. During typing in a document however, the load on the CPU should be as minimal as possible so only the current document will be checked with `document_check_disk_status(.., gboolean force)`. The latter may _avalanche_ to check all others too, if for the first time a change is detected. Why is this needed?
The information to display is not static, nor similar for each document: 1. One file maybe saved by the user, while the others are handled later on. So the number of modified (or deleted) files will be decreased every time, for each monitor widget. 2. The information is not similar for each monitor widget, therefore it needs a macro `foreach_document_skip(i,skip)` to list all other names, see screenshot below.
The consequence is that we need to disentangle two tasks: collecting the information first, then displaying it as a second action later. Making a list and modifying it later on, becomes quite error prone, giving the dynamic change above: it is just easier to iterate of the documents while constructing a new or updated monitor widget.
Will the widgets be updated every time? No, only when the a change is detected, for which I use the boolean variable `modified_since_roundtrip`. I worry about wasting needless CPU cycles too, see an earlier problem I [solved](https://gitlab.gnome.org/GNOME/eog/-/commit/30a5007b3c4dea76eafe176bdf3b7411...). Mind that it is still work in progress (WIP), I'll only send a PR once, to my knowledge, no new bug are added and the functionality is complete.
![geany_disk_summary](https://github.com/geany/geany/assets/7198614/222f40c4-6264-4d98-ab7b-ff7394...)
Closed #3711 as completed.
As OP, this issue is outdated. See also [here](https://github.com/geany/geany/issues/2540).
github-comments@lists.geany.org