Le 10/05/2017 à 22:57, Stephan Witt a écrit :
Am 09.05.2017 um 21:19 schrieb john kennan <jken...@ssc.wisc.edu>:

Start a new file
type something
save
type some more
save

I get "the file ... changed on disk." with two buttons: "Reload" and "Ignore"

hitting Ignore leaves the file unsaved
hitting Reload works -- I get a warning:

Any changes will be lost. Are you sure you want to load the version on disk of 
the document .../Papers/LyX/test1.lyx?

with buttons for Revert and Cancel
Hitting Revert saves the file, as desired, and the changes are not lost.

Dear John, thanks for the report. This looks like LyX incorrectly
recording the modification it has made itself as an external
modification. This means that in fact the file is already correctly
saved when the message shows up, and the two buttons do nothing except
annoy. I am looking into it.

Does it happen only on the second save? Does it happen on the third save
if you carry on? Does it not happen on the first save? If not, is it
because the first save is a "Save As"?


Confirmed.

Dear Stephan, thanks for the test. This looks specific to OSX. I would
ask the same questions as above.


Guillaume, it’s the FileMonitor which is detecting the file save as external 
modification.
How can I provide further info to correct this annoying behavior?
My attempt to diagnose the culprit failed - the code is too weird for me :(

I tried to stop in Buffer::Impl::refreshFileMonitor() at the first line.
The debugger didn’t stop - but it stopped in 
Buffer::Impl::fileExternallyModified()
and the call stack claims it comes from the last line in refreshFileMonitor() 
???

As QFileSystemWatcher is intrinsically asynchronous, gdb does not really
help with debugging here. What you see on the trace is
QFileSystemWatcher calling the function that was passed to connect at
the end of refreshFileMonitor (via a qt signal that is converted into a
boost signal).

What should happen is inside Buffer::save there is a FileMonitorBlocker
that should block the signal. Now, since QFileSystemWatcher is
asynchronous, the signal is not received before the next iteration of
the even loop. At this point the FileMonitorBlocker has been destroyed a
long time ago. This is why FileMonitorBlocker unblocks the signal in an
asynchronous way too, using a QTimer. On Linux, a delay of 0 (meaning
wait until the next event loop) is enough to actually block the signal.

The delay is defined in Buffer::Impl::blockFileMonitor (Buffer.cpp:388)
currently at 10ms. Can you try to increase this value and see if that
helps? It will likely help, but this is not a nice solution.

Ideally I would like to have everything work with a delay of 0ms, to be
sure that everyone experiences the same. Can you help me and see if it
is possible to flush the file operations in FileName::copyTo and
FileName::moveTo and if it makes a difference ? There is QFile::flush
but I do not really see how to use it in this context and I cannot test
the situation.


Frankly said: I’m lost now.

For this bug and the other similar bug on the bugtracker [down currently
again] I thought about detecting false positives by comparing the file
hashes before setting the flag.

Before this drastic measure I would like to see if I can understand why
the signal comes too late for the blocker, and if it's just missing
something simple.


Guillaume



Reply via email to