]> git.lyx.org Git - lyx.git/blob - development/gcc_4.6.patchset
Use data from src/lyxwinres.rc to generate lyx.coff for the Windows
[lyx.git] / development / gcc_4.6.patchset
1 commit 465cd79bcbab3e036cf86ab4682386c255a91eb6
2 Author: Pavel Sanda <psanda@ucsd.edu>
3 Date:   Thu Nov 16 09:33:29 2017 -0800
4
5     move initialization so older gcc still works
6
7 diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
8 index 68ef3b9..b76138b 100644
9 --- a/src/frontends/qt4/GuiView.cpp
10 +++ b/src/frontends/qt4/GuiView.cpp
11 @@ -508,7 +508,7 @@ QSet<Buffer const *> GuiView::GuiViewPrivate::busyBuffers;
12  
13  GuiView::GuiView(int id)
14         : d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0),
15 -         command_execute_(false), minibuffer_focus_(false), devel_mode_(false)
16 +         command_execute_(false), minibuffer_focus_(false), zoom_ratio_(1.0), devel_mode_(false)
17  {
18         connect(this, SIGNAL(bufferViewChanged()),
19                 this, SLOT(onBufferViewChanged()));
20 diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h
21 index ecf4e44..ed80ca3 100644
22 --- a/src/frontends/qt4/GuiView.h
23 +++ b/src/frontends/qt4/GuiView.h
24 @@ -472,7 +472,7 @@ private:
25  
26         /// The rate from which the actual zoom value is calculated
27         /// from the default zoom pref
28 -       double zoom_ratio_ = 1.0;
29 +       double zoom_ratio_;
30         /// Minimum zoom percentage
31         static int const zoom_min_ = 10;
32  
33
34 commit de8c60ba2a3779b31a1d8526541a9583b076221c
35 Author: Pavel Sanda <psanda@ucsd.edu>
36 Date:   Thu Nov 16 09:15:07 2017 -0800
37
38     Revert b30161b59 (Remove FileMonitorBlocker which does not work reliably on all platforms)
39
40 diff --git a/src/Buffer.cpp b/src/Buffer.cpp
41 index 9ec20e0..6e37ee9 100644
42 --- a/src/Buffer.cpp
43 +++ b/src/Buffer.cpp
44 @@ -383,6 +383,9 @@ public:
45         /// Notify or clear of external modification
46         void fileExternallyModified(bool exists);
47  
48 +       /// Block notifications of external modifications
49 +       FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(); }
50 +
51         /// has been externally modified? Can be reset by the user.
52         mutable bool externally_modified_;
53  
54 @@ -1379,6 +1382,7 @@ FileName Buffer::getBackupName() const {
55  // Should probably be moved to somewhere else: BufferView? GuiView?
56  bool Buffer::save() const
57  {
58 +       FileMonitorBlocker block = d->blockFileMonitor();
59         docstring const file = makeDisplayPath(absFileName(), 20);
60         d->filename.refresh();
61  
62 @@ -5344,7 +5348,8 @@ void Buffer::Impl::refreshFileMonitor()
63  
64  void Buffer::Impl::fileExternallyModified(bool const exists)
65  {
66 -       // ignore notifications after our own saving operations
67 +       // prevent false positives, because FileMonitorBlocker is not enough on
68 +       // OSX.
69         if (checksum_ == filename.checksum()) {
70                 LYXERR(Debug::FILES, "External modification but "
71                        "checksum unchanged: " << filename);
72 diff --git a/src/support/FileMonitor.cpp b/src/support/FileMonitor.cpp
73 index c703d2b..2a794f2 100644
74 --- a/src/support/FileMonitor.cpp
75 +++ b/src/support/FileMonitor.cpp
76 @@ -202,6 +202,42 @@ void FileMonitor::changed(bool const exists)
77  }
78  
79  
80 +FileMonitorBlocker FileMonitor::block(int delay)
81 +{
82 +       FileMonitorBlocker blocker = blocker_.lock();
83 +       if (!blocker)
84 +               blocker_ = blocker = make_shared<FileMonitorBlockerGuard>(this);
85 +       blocker->setDelay(delay);
86 +       return blocker;
87 +}
88 +
89 +
90 +FileMonitorBlockerGuard::FileMonitorBlockerGuard(FileMonitor * monitor)
91 +       : monitor_(monitor), delay_(0)
92 +{
93 +       QObject::disconnect(monitor->monitor_.get(), SIGNAL(fileChanged(bool)),
94 +                           monitor, SLOT(changed(bool)));
95 +}
96 +
97 +
98 +void FileMonitorBlockerGuard::setDelay(int delay)
99 +{
100 +       delay_ = max(delay_, delay);
101 +}
102 +
103 +
104 +FileMonitorBlockerGuard::~FileMonitorBlockerGuard()
105 +{
106 +       if (!monitor_)
107 +               return;
108 +       // Even if delay_ is 0, the QTimer is necessary. Indeed, the notifications
109 +       // from QFileSystemWatcher that we meant to ignore are not going to be
110 +       // treated immediately, so we must yield to give us the opportunity to
111 +       // ignore them.
112 +       QTimer::singleShot(delay_, monitor_, SLOT(connectToFileMonitorGuard()));
113 +}
114 +
115 +
116  ActiveFileMonitor::ActiveFileMonitor(std::shared_ptr<FileMonitorGuard> monitor,
117                                       FileName const & filename, int interval)
118         : FileMonitor(monitor), filename_(filename), interval_(interval),
119 diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h
120 index 14aa834..fdf2bca 100644
121 --- a/src/support/FileMonitor.h
122 +++ b/src/support/FileMonitor.h
123 @@ -60,6 +60,12 @@ typedef std::unique_ptr<ActiveFileMonitor> ActiveFileMonitorPtr;
124  ///   monitor.connect(...);
125  /// (stops watching the first)
126  ///
127 +/// Block notifications for the duration of a scope:
128 +///   {
129 +///       FileMonitorBlocker block = monitor.block();
130 +///       ...
131 +///   }
132 +///
133  /// Reset connections:
134  ///   monitor.disconnect();
135  ///   or the disconnect method of the connection object for the boost signal.
136 @@ -125,10 +131,27 @@ private:
137  };
138  
139  
140 +class FileMonitorBlockerGuard : public QObject
141 +{
142 +       Q_OBJECT
143 +       QPointer<FileMonitor> monitor_;
144 +       int delay_;
145 +
146 +public:
147 +       FileMonitorBlockerGuard(FileMonitor * monitor);
148 +       ~FileMonitorBlockerGuard();
149 +       void setDelay(int delay);
150 +};
151 +
152 +
153 +typedef std::shared_ptr<FileMonitorBlockerGuard> FileMonitorBlocker;
154 +
155 +
156  /// Main class
157  class FileMonitor : public QObject
158  {
159         Q_OBJECT
160 +       friend class FileMonitorBlockerGuard;
161  
162  public:
163         FileMonitor(std::shared_ptr<FileMonitorGuard> monitor);
164 @@ -142,6 +165,20 @@ public:
165         void disconnect();
166         /// absolute path being tracked
167         std::string const & filename() { return monitor_->filename(); }
168 +       /// Creates a guard that blocks notifications. Copyable. Notifications from
169 +       /// this monitor are blocked as long as there are copies of the
170 +       /// FileMonitorBlocker around.
171 +       /// \param delay is the amount waited in ms after expiration of the guard
172 +       /// before reconnecting. It can be used to slow down incoming events
173 +       /// accordingly. A value of 0 is still made asynchronous, because of the
174 +       /// fundamentally asynchronous nature of QFileSystemWatcher. To catch one's
175 +       /// own file operations, a value of 0 for delay is sufficient with the
176 +       /// inotify backend (e.g. Linux); for OSX (kqueue), a value of 100ms is
177 +       /// unsufficient and more tests need to be done in combination with
178 +       /// flushing/syncing to disk in order to understand how to catch one's own
179 +       /// operations reliably. No feedback about Windows. See
180 +       /// <https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg200252.html>.
181 +       FileMonitorBlocker block(int delay = 0);
182         /// Make sure the good file is being monitored, after e.g. a move or a
183         /// deletion. See <https://bugreports.qt.io/browse/QTBUG-46483>. This is
184         /// called automatically.
185 @@ -162,6 +199,8 @@ private:
186         sig fileChanged_;
187         /// the unique watch for our file
188         std::shared_ptr<FileMonitorGuard> const monitor_;
189 +       ///
190 +       std::weak_ptr<FileMonitorBlockerGuard> blocker_;
191  };
192  
193  
194
195 commit ab4584d9a5747aad2c23cf7b26ee05a30de89bc9
196 Author: Pavel Sanda <psanda@ucsd.edu>
197 Date:   Thu Nov 16 09:22:11 2017 -0800
198
199     Revert b30161b591264f : If the external modification is a deletion, do not ask for reloading.
200
201 diff --git a/src/Buffer.cpp b/src/Buffer.cpp
202 index 6e37ee9..b83f872 100644
203 --- a/src/Buffer.cpp
204 +++ b/src/Buffer.cpp
205 @@ -380,15 +380,15 @@ public:
206         // Make sure the file monitor monitors the good file.
207         void refreshFileMonitor();
208  
209 +       /// has it been notified of an external modification?
210 +       bool isExternallyModified() const { return externally_modified_; }
211 +
212         /// Notify or clear of external modification
213 -       void fileExternallyModified(bool exists);
214 +       void fileExternallyModified(bool modified);
215  
216         /// Block notifications of external modifications
217         FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(); }
218  
219 -       /// has been externally modified? Can be reset by the user.
220 -       mutable bool externally_modified_;
221 -
222  private:
223         /// So we can force access via the accessors.
224         mutable Buffer const * parent_buffer;
225 @@ -397,6 +397,9 @@ private:
226         int char_count_;
227         int blank_count_;
228  
229 +       /// has been externally modified? Can be reset by the user.
230 +       mutable bool externally_modified_;
231 +
232         FileMonitorPtr file_monitor_;
233  };
234  
235 @@ -438,8 +441,9 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_,
236           bibfile_cache_valid_(false), cite_labels_valid_(false), preview_error_(false),
237           inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer),
238           clone_list_(0), doing_export(false),
239 -         tracked_changes_present_(0), externally_modified_(false), parent_buffer(0),
240 -         word_count_(0), char_count_(0), blank_count_(0)
241 +         tracked_changes_present_(0), parent_buffer(0),
242 +         word_count_(0), char_count_(0), blank_count_(0),
243 +         externally_modified_(false)
244  {
245         refreshFileMonitor();
246         if (!cloned_buffer_) {
247 @@ -5338,29 +5342,26 @@ void Buffer::Impl::refreshFileMonitor()
248         // The previous file monitor is invalid
249         // This also destroys the previous file monitor and all its connections
250         file_monitor_ = FileSystemWatcher::monitor(filename);
251 +       fileExternallyModified(false);
252         // file_monitor_ will be destroyed with *this, so it is not going to call a
253         // destroyed object method.
254 -       file_monitor_->connect([this](bool exists) {
255 -                       fileExternallyModified(exists);
256 -               });
257 +       file_monitor_->connect([this](){ fileExternallyModified(true); });
258  }
259  
260  
261  void Buffer::Impl::fileExternallyModified(bool const exists)
262  {
263 -       // prevent false positives, because FileMonitorBlocker is not enough on
264 -       // OSX.
265 -       if (checksum_ == filename.checksum()) {
266 +       if (modified) {
267 +               // prevent false positives, because FileMonitorBlocker is not enough on
268 +               // OSX.
269 +               if (filename.exists() && checksum_ == filename.checksum()) {
270                 LYXERR(Debug::FILES, "External modification but "
271 -                      "checksum unchanged: " << filename);
272 +                       "checksum unchanged: " << filename);
273                 return;
274 +               }
275 +               lyx_clean = bak_clean = false;
276         }
277 -       lyx_clean = bak_clean = false;
278 -       // If the file has been deleted, only mark the file as dirty since it is
279 -       // pointless to prompt for reloading. If later a file is moved into this
280 -       // location, then the externally modified warning will appear then.
281 -       if (exists)
282 -                       externally_modified_ = true;
283 +       externally_modified_ = modified;
284         // Update external modification notification.
285         // Dirty buffers must be visible at all times.
286         if (wa_ && wa_->unhide(owner_))
287 @@ -5373,15 +5374,13 @@ void Buffer::Impl::fileExternallyModified(bool const exists)
288  
289  bool Buffer::notifiesExternalModification() const
290  {
291 -       return d->externally_modified_;
292 +       return d->isExternallyModified();
293  }
294  
295  
296  void Buffer::clearExternalModification() const
297  {
298 -       d->externally_modified_ = false;
299 -       if (d->wa_)
300 -               d->wa_->updateTitles();
301 +       d->fileExternallyModified(false);
302  }
303  
304  
305 diff --git a/src/graphics/GraphicsCacheItem.cpp b/src/graphics/GraphicsCacheItem.cpp
306 index f54ce80..576ad92 100644
307 --- a/src/graphics/GraphicsCacheItem.cpp
308 +++ b/src/graphics/GraphicsCacheItem.cpp
309 @@ -220,7 +220,7 @@ void CacheItem::Impl::startMonitor()
310                 return;
311         monitor_ = FileSystemWatcher::activeMonitor(filename_);
312         // Disconnected at the same time as this is destroyed.
313 -       monitor_->connect([=](bool /* exists */){ startLoading(); });
314 +       monitor_->connect([=](){ startLoading(); });
315  }
316  
317  
318 diff --git a/src/insets/RenderPreview.cpp b/src/insets/RenderPreview.cpp
319 index df0ac64..18882fc 100644
320 --- a/src/insets/RenderPreview.cpp
321 +++ b/src/insets/RenderPreview.cpp
322 @@ -304,7 +304,7 @@ void RenderMonitoredPreview::startMonitoring() const
323  {
324         if (!monitoring()) {
325                 monitor_ = FileSystemWatcher::activeMonitor(filename_);
326 -               monitor_->connect([this](bool /* exists */){ changed_(); });
327 +               monitor_->connect(changed_);
328         }
329  }
330  
331 diff --git a/src/support/FileMonitor.cpp b/src/support/FileMonitor.cpp
332 index 2a794f2..f1fefb8 100644
333 --- a/src/support/FileMonitor.cpp
334 +++ b/src/support/FileMonitor.cpp
335 @@ -118,37 +118,31 @@ FileMonitorGuard::~FileMonitorGuard()
336  }
337  
338  
339 -void FileMonitorGuard::refresh(bool const emit)
340 +void FileMonitorGuard::refresh()
341  {
342         if (filename_.empty())
343                 return;
344         QString const qfilename = toqstr(filename_);
345 -       if (!qwatcher_->files().contains(qfilename)) {
346 -               bool const existed = exists_;
347 -               exists_ = QFile(qfilename).exists();
348 +       if(!qwatcher_->files().contains(qfilename)) {
349 +               bool exists = QFile(qfilename).exists();
350  #if (QT_VERSION >= 0x050000)
351 -               if (exists_ && !qwatcher_->addPath(qfilename))
352 +               if (!exists || !qwatcher_->addPath(qfilename))
353  #else
354                 auto add_path = [&]() {
355                         qwatcher_->addPath(qfilename);
356                         return qwatcher_->files().contains(qfilename);
357                 };
358 -               if (exists_ && !add_path())
359 +               if (!exists || !add_path())
360  #endif
361                 {
362 -                       LYXERR(Debug::FILES,
363 -                              "Could not add path to QFileSystemWatcher: " << filename_);
364 -                       QTimer::singleShot(5000, this, SLOT(refresh()));
365 -               } else {
366 -                       if (!exists_)
367 -                               // The standard way to overwrite a file is to delete it and
368 -                               // create a new file with the same name. Therefore if the file
369 -                               // has just been deleted, it is smart to check not too long
370 -                               // after whether it has been recreated.
371 -                           QTimer::singleShot(existed ? 100 : 2000, this, SLOT(refresh()));
372 -                       if (existed != exists_ && emit)
373 -                               Q_EMIT fileChanged(exists_);
374 -               }
375 +                       if (exists)
376 +                               LYXERR(Debug::FILES,
377 +                                      "Could not add path to QFileSystemWatcher: "
378 +                                      << filename_);
379 +                       QTimer::singleShot(2000, this, SLOT(refresh()));
380 +               } else if (exists && !exists_)
381 +                       Q_EMIT fileChanged();
382 +               setExists(exists);
383         }
384  }
385  
386 @@ -156,12 +150,11 @@ void FileMonitorGuard::refresh(bool const emit)
387  void FileMonitorGuard::notifyChange(QString const & path)
388  {
389         if (path == toqstr(filename_)) {
390 +               Q_EMIT fileChanged();
391                 // If the file has been modified by delete-move, we are notified of the
392                 // deletion but we no longer track the file. See
393                 // <https://bugreports.qt.io/browse/QTBUG-46483> (not a bug).
394 -               // Therefore we must refresh.
395 -               refresh(false);
396 -               Q_EMIT fileChanged(exists_);
397 +               refresh();
398         }
399  }
400  
401 @@ -169,15 +162,17 @@ void FileMonitorGuard::notifyChange(QString const & path)
402  FileMonitor::FileMonitor(std::shared_ptr<FileMonitorGuard> monitor)
403         : monitor_(monitor)
404  {
405 -       connectToFileMonitorGuard();
406 +       QObject::connect(monitor_.get(), SIGNAL(fileChanged()),
407 +                        this, SLOT(changed()));
408         refresh();
409  }
410  
411  
412 -void FileMonitor::connectToFileMonitorGuard()
413 +void FileMonitor::reconnectToFileMonitorGuard()
414  {
415 -       QObject::connect(monitor_.get(), SIGNAL(fileChanged(bool)),
416 -                        this, SLOT(changed(bool)));
417 +       monitor_->setExists(true);
418 +       QObject::connect(monitor_.get(), SIGNAL(fileChanged()),
419 +                        this, SLOT(changed()));
420  }
421  
422  
423 @@ -190,15 +185,15 @@ signals2::connection FileMonitor::connect(slot const & slot)
424  void FileMonitor::disconnect()
425  {
426         fileChanged_.disconnect_all_slots();
427 -       QObject::disconnect(this, SIGNAL(fileChanged(bool)));
428 +       QObject::disconnect(this, SIGNAL(fileChanged()));
429  }
430  
431  
432 -void FileMonitor::changed(bool const exists)
433 +void FileMonitor::changed()
434  {
435         // emit boost signal
436 -       fileChanged_(exists);
437 -       Q_EMIT fileChanged(exists);
438 +       fileChanged_();
439 +       Q_EMIT fileChanged();
440  }
441  
442  
443 @@ -215,8 +210,8 @@ FileMonitorBlocker FileMonitor::block(int delay)
444  FileMonitorBlockerGuard::FileMonitorBlockerGuard(FileMonitor * monitor)
445         : monitor_(monitor), delay_(0)
446  {
447 -       QObject::disconnect(monitor->monitor_.get(), SIGNAL(fileChanged(bool)),
448 -                           monitor, SLOT(changed(bool)));
449 +       QObject::disconnect(monitor->monitor_.get(), SIGNAL(fileChanged()),
450 +                           monitor, SLOT(changed()));
451  }
452  
453  
454 @@ -234,7 +229,7 @@ FileMonitorBlockerGuard::~FileMonitorBlockerGuard()
455         // from QFileSystemWatcher that we meant to ignore are not going to be
456         // treated immediately, so we must yield to give us the opportunity to
457         // ignore them.
458 -       QTimer::singleShot(delay_, monitor_, SLOT(connectToFileMonitorGuard()));
459 +       QTimer::singleShot(delay_, monitor_, SLOT(reconnectToFileMonitorGuard()));
460  }
461  
462  
463 @@ -243,9 +238,8 @@ ActiveFileMonitor::ActiveFileMonitor(std::shared_ptr<FileMonitorGuard> monitor,
464         : FileMonitor(monitor), filename_(filename), interval_(interval),
465           timestamp_(0), checksum_(0), cooldown_(true)
466  {
467 -       QObject::connect(this, SIGNAL(fileChanged(bool)), this, SLOT(setCooldown()));
468 +       QObject::connect(this, SIGNAL(fileChanged()), this, SLOT(setCooldown()));
469         QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
470 -       filename_.refresh();
471         if (!filename_.exists())
472                 return;
473         timestamp_ = filename_.lastModified();
474 @@ -260,9 +254,7 @@ void ActiveFileMonitor::checkModified()
475  
476         cooldown_ = true;
477         bool changed = false;
478 -       filename_.refresh();
479 -       bool exists = filename_.exists();
480 -       if (!exists) {
481 +       if (!filename_.exists()) {
482                 changed = timestamp_ || checksum_;
483                 timestamp_ = 0;
484                 checksum_ = 0;
485 @@ -280,7 +272,7 @@ void ActiveFileMonitor::checkModified()
486                 }
487         }
488         if (changed)
489 -               FileMonitor::changed(exists);
490 +               FileMonitor::changed();
491         QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
492  }
493  
494 diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h
495 index fdf2bca..5e516bb 100644
496 --- a/src/support/FileMonitor.h
497 +++ b/src/support/FileMonitor.h
498 @@ -108,16 +108,18 @@ public:
499         ~FileMonitorGuard();
500         /// absolute path being tracked
501         std::string const & filename() { return filename_; }
502 +       /// if false, emit fileChanged() when we notice the existence of the file
503 +       void setExists(bool exists) { exists_ = exists; }
504  
505  public Q_SLOTS:
506         /// Make sure it is being monitored, after e.g. a deletion. See
507         /// <https://bugreports.qt.io/browse/QTBUG-46483>. This is called
508         /// automatically.
509 -       void refresh(bool emit = true);
510 +       void refresh();
511  
512  Q_SIGNALS:
513         /// Connect to this to be notified when the file changes
514 -       void fileChanged(bool exists) const;
515 +       void fileChanged() const;
516  
517  private Q_SLOTS:
518         /// Receive notifications from the QFileSystemWatcher
519 @@ -126,7 +128,6 @@ private Q_SLOTS:
520  private:
521         std::string const filename_;
522         QFileSystemWatcher * qwatcher_;
523 -       /// for emitting fileChanged() when the file is created or deleted
524         bool exists_;
525  };
526  
527 @@ -156,7 +157,7 @@ class FileMonitor : public QObject
528  public:
529         FileMonitor(std::shared_ptr<FileMonitorGuard> monitor);
530  
531 -       typedef signals2::signal<void(bool)> sig;
532 +       typedef signals2::signal<void()> sig;
533         typedef sig::slot_type slot;
534         /// Connect and you'll be informed when the file has changed.
535         signals2::connection connect(slot const &);
536 @@ -176,7 +177,7 @@ public:
537         /// inotify backend (e.g. Linux); for OSX (kqueue), a value of 100ms is
538         /// unsufficient and more tests need to be done in combination with
539         /// flushing/syncing to disk in order to understand how to catch one's own
540 -       /// operations reliably. No feedback about Windows. See
541 +       /// operations reliably. No feedback from Windows yet. See
542         /// <https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg200252.html>.
543         FileMonitorBlocker block(int delay = 0);
544         /// Make sure the good file is being monitored, after e.g. a move or a
545 @@ -186,13 +187,13 @@ public:
546  
547  Q_SIGNALS:
548         /// Connect to this to be notified when the file changes
549 -       void fileChanged(bool exists) const;
550 +       void fileChanged() const;
551  
552  protected Q_SLOTS:
553         /// Receive notifications from the FileMonitorGuard
554 -       void changed(bool exists);
555 +       void changed();
556         ///
557 -       void connectToFileMonitorGuard();
558 +       void reconnectToFileMonitorGuard();
559  
560  private:
561         /// boost signal
562
563 commit f1c415f3b0ae9ddea5548742f5300e86e95480f2
564 Author: Pavel Sanda <psanda@ucsd.edu>
565 Date:   Thu Nov 16 09:24:31 2017 -0800
566
567     Revert 2058faaa3bd: Prevent false positives in external modifications
568
569 diff --git a/src/Buffer.cpp b/src/Buffer.cpp
570 index b83f872..48391f9 100644
571 --- a/src/Buffer.cpp
572 +++ b/src/Buffer.cpp
573 @@ -387,7 +387,7 @@ public:
574         void fileExternallyModified(bool modified);
575  
576         /// Block notifications of external modifications
577 -       FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(); }
578 +       FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(10); }
579  
580  private:
581         /// So we can force access via the accessors.
582 @@ -5351,16 +5351,8 @@ void Buffer::Impl::refreshFileMonitor()
583  
584  void Buffer::Impl::fileExternallyModified(bool const exists)
585  {
586 -       if (modified) {
587 -               // prevent false positives, because FileMonitorBlocker is not enough on
588 -               // OSX.
589 -               if (filename.exists() && checksum_ == filename.checksum()) {
590 -               LYXERR(Debug::FILES, "External modification but "
591 -                       "checksum unchanged: " << filename);
592 -               return;
593 -               }
594 +       if (modified) 
595                 lyx_clean = bak_clean = false;
596 -       }
597         externally_modified_ = modified;
598         // Update external modification notification.
599         // Dirty buffers must be visible at all times.
600 diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h
601 index 5e516bb..49f12cb 100644
602 --- a/src/support/FileMonitor.h
603 +++ b/src/support/FileMonitor.h
604 @@ -167,18 +167,11 @@ public:
605         /// absolute path being tracked
606         std::string const & filename() { return monitor_->filename(); }
607         /// Creates a guard that blocks notifications. Copyable. Notifications from
608 -       /// this monitor are blocked as long as there are copies of the
609 -       /// FileMonitorBlocker around.
610 +       /// this monitor are blocked as long as there are copies around.
611         /// \param delay is the amount waited in ms after expiration of the guard
612 -       /// before reconnecting. It can be used to slow down incoming events
613 -       /// accordingly. A value of 0 is still made asynchronous, because of the
614 -       /// fundamentally asynchronous nature of QFileSystemWatcher. To catch one's
615 -       /// own file operations, a value of 0 for delay is sufficient with the
616 -       /// inotify backend (e.g. Linux); for OSX (kqueue), a value of 100ms is
617 -       /// unsufficient and more tests need to be done in combination with
618 -       /// flushing/syncing to disk in order to understand how to catch one's own
619 -       /// operations reliably. No feedback from Windows yet. See
620 -       /// <https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg200252.html>.
621 +       /// before reconnecting. This delay thing is to deal with asynchronous
622 +       /// notifications in a not so elegant fashion. But it can also be used to
623 +       /// slow down incoming events.
624         FileMonitorBlocker block(int delay = 0);
625         /// Make sure the good file is being monitored, after e.g. a move or a
626         /// deletion. See <https://bugreports.qt.io/browse/QTBUG-46483>. This is
627
628 commit 96a893b5564404f80a2fd42b7a559d3306babce2
629 Author: Pavel Sanda <psanda@ucsd.edu>
630 Date:   Thu Nov 16 09:25:19 2017 -0800
631
632     Revert db581113: roperly track the lifetime of signals2::slots (#8261)
633
634 diff --git a/src/Converter.cpp b/src/Converter.cpp
635 index 664a4bb..6e26ed2 100644
636 --- a/src/Converter.cpp
637 +++ b/src/Converter.cpp
638 @@ -786,6 +786,20 @@ bool Converters::scanLog(Buffer const & buffer, string const & /*command*/,
639  }
640  
641  
642 +namespace {
643 +
644 +class ShowMessage
645 +       : public boost::signals2::trackable {
646 +public:
647 +       ShowMessage(Buffer const & b) : buffer_(b) {}
648 +       void operator()(docstring const & msg) const { buffer_.message(msg); }
649 +private:
650 +       Buffer const & buffer_;
651 +};
652 +
653 +}
654 +
655 +
656  bool Converters::runLaTeX(Buffer const & buffer, string const & command,
657                           OutputParams const & runparams, ErrorList & errorList)
658  {
659 @@ -798,12 +812,8 @@ bool Converters::runLaTeX(Buffer const & buffer, string const & command,
660                     buffer.filePath(), buffer.layoutPos(),
661                     buffer.lastPreviewError());
662         TeXErrors terr;
663 -       // The connection closes itself at the end of the scope when latex is
664 -       // destroyed. One cannot close (and destroy) buffer while the converter is
665 -       // running.
666 -       latex.message.connect([&buffer](docstring const & msg){
667 -                       buffer.message(msg);
668 -               });
669 +       ShowMessage show(buffer);
670 +       latex.message.connect(show);
671         int const result = latex.run(terr);
672  
673         if (result & LaTeX::ERRORS)
674 diff --git a/src/LaTeX.h b/src/LaTeX.h
675 index 0b46c60..b2d6ac0 100644
676 --- a/src/LaTeX.h
677 +++ b/src/LaTeX.h
678 @@ -18,7 +18,8 @@
679  
680  #include "support/docstring.h"
681  #include "support/FileName.h"
682 -#include "support/signals.h"
683 +
684 +#include <boost/signals2.hpp>
685  
686  #include <vector>
687  #include <set>
688 @@ -147,7 +148,7 @@ public:
689         };
690  
691         /// This signal emits an informative message
692 -       signals2::signal<void(docstring)> message;
693 +       boost::signals2::signal<void(docstring)> message;
694  
695  
696         /**
697 diff --git a/src/Server.cpp b/src/Server.cpp
698 index 8953c78..debb8a9 100644
699 --- a/src/Server.cpp
700 +++ b/src/Server.cpp
701 @@ -55,7 +55,8 @@
702  #include "support/lassert.h"
703  #include "support/lstrings.h"
704  #include "support/os.h"
705 -#include "support/signals.h"
706 +
707 +#include "support/bind.h"
708  
709  #include <iostream>
710  
711 @@ -858,12 +859,8 @@ int LyXComm::startPipe(string const & file, bool write)
712         }
713  
714         if (!write) {
715 -               // Make sure not to call read_ready after destruction.
716 -               weak_ptr<void> tracker = tracker_.p();
717 -               theApp()->registerSocketCallback(fd, [=](){
718 -                               if (!tracker.expired())
719 -                                       read_ready();
720 -                       });
721 +               theApp()->registerSocketCallback(fd,
722 +                       bind(&LyXComm::read_ready, this));
723         }
724  
725         return fd;
726 diff --git a/src/Server.h b/src/Server.h
727 index 40021da..1a46c89 100644
728 --- a/src/Server.h
729 +++ b/src/Server.h
730 @@ -14,7 +14,7 @@
731  #ifndef SERVER_H
732  #define SERVER_H
733  
734 -#include "support/signals.h"
735 +#include <boost/signals2/trackable.hpp>
736  
737  #include <vector>
738  
739 @@ -30,7 +30,7 @@ namespace lyx {
740  class Server;
741  
742  
743 -/** This class manages the pipes used for communicating with clients.
744 +/** This class managed the pipes used for communicating with clients.
745   Usage: Initialize with pipe-filename-base, client class to receive
746   messages, and callback-function that will be called with the messages.
747   When you want to send, use "send()".
748 @@ -38,7 +38,7 @@ class Server;
749   a clean string interface.
750   */
751  #ifndef _WIN32
752 -class LyXComm {
753 +class LyXComm : public boost::signals2::trackable {
754  #else
755  class LyXComm : public QObject {
756         Q_OBJECT
757 @@ -189,9 +189,6 @@ private:
758  
759         /// Did we defer loading of files to another instance?
760         bool deferred_loading_;
761 -
762 -       /// Track object's liveness
763 -       support::Trackable tracker_;
764  };
765  
766  
767 diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
768 index c587460..68ef3b9 100644
769 --- a/src/frontends/qt4/GuiView.cpp
770 +++ b/src/frontends/qt4/GuiView.cpp
771 @@ -529,8 +529,7 @@ GuiView::GuiView(int id)
772  
773         // Start autosave timer
774         if (lyxrc.autosave) {
775 -               // The connection is closed when this is destroyed.
776 -               d.autosave_timeout_.timeout.connect([this](){ autoSave();});
777 +               d.autosave_timeout_.timeout.connect(bind(&GuiView::autoSave, this));
778                 d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000);
779                 d.autosave_timeout_.start();
780         }
781 diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp
782 index fe7082d..d7c7b00 100644
783 --- a/src/frontends/qt4/GuiWorkArea.cpp
784 +++ b/src/frontends/qt4/GuiWorkArea.cpp
785 @@ -320,10 +320,9 @@ void GuiWorkArea::init()
786  
787         d->setCursorShape(Qt::IBeamCursor);
788  
789 -       // This connection is closed at the same time as this is destroyed.
790 -       d->synthetic_mouse_event_.timeout.timeout.connect([this](){
791 -                       generateSyntheticMouseEvent();
792 -               });
793 +       d->synthetic_mouse_event_.timeout.timeout.connect(
794 +               bind(&GuiWorkArea::generateSyntheticMouseEvent,
795 +                                       this));
796  
797         LYXERR(Debug::GUI, "viewport width: " << viewport()->width()
798                 << "  viewport height: " << viewport()->height());
799 diff --git a/src/graphics/GraphicsCacheItem.cpp b/src/graphics/GraphicsCacheItem.cpp
800 index 576ad92..306dcdb 100644
801 --- a/src/graphics/GraphicsCacheItem.cpp
802 +++ b/src/graphics/GraphicsCacheItem.cpp
803 @@ -29,6 +29,7 @@
804  #include "support/lassert.h"
805  #include "support/unique_ptr.h"
806  
807 +#include "support/bind.h"
808  #include "support/TempFile.h"
809  
810  using namespace std;
811 @@ -38,7 +39,7 @@ namespace lyx {
812  
813  namespace graphics {
814  
815 -class CacheItem::Impl {
816 +class CacheItem::Impl : public boost::signals2::trackable {
817  public:
818  
819         ///
820 @@ -49,7 +50,7 @@ public:
821         /**
822          *  If no file conversion is needed, then tryDisplayFormat() calls
823          *  loadImage() directly.
824 -        * \return true if a conversion is necessary and no error occurred.
825 +        * \return true if a conversion is necessary and no error occurred. 
826          */
827         bool tryDisplayFormat(FileName & filename, string & from);
828  
829 @@ -119,7 +120,10 @@ public:
830         ImageStatus status_;
831  
832         /// This signal is emitted when the image loading status changes.
833 -       signals2::signal<void()> statusChanged;
834 +       boost::signals2::signal<void()> statusChanged;
835 +
836 +       /// The connection of the signal ConvProcess::finishedConversion,
837 +       boost::signals2::connection cc_;
838  
839         ///
840         unique_ptr<Converter> converter_;
841 @@ -195,7 +199,7 @@ ImageStatus CacheItem::status() const
842  }
843  
844  
845 -signals2::connection CacheItem::connect(slot_type const & slot) const
846 +boost::signals2::connection CacheItem::connect(slot_type const & slot) const
847  {
848         return pimpl_->statusChanged.connect(slot);
849  }
850 @@ -219,7 +223,6 @@ void CacheItem::Impl::startMonitor()
851         if (monitor_)
852                 return;
853         monitor_ = FileSystemWatcher::activeMonitor(filename_);
854 -       // Disconnected at the same time as this is destroyed.
855         monitor_->connect([=](){ startLoading(); });
856  }
857  
858 @@ -251,6 +254,9 @@ void CacheItem::Impl::reset()
859  
860         status_ = WaitingToLoad;
861  
862 +       if (cc_.connected())
863 +               cc_.disconnect();
864 +
865         if (converter_)
866                 converter_.reset();
867  }
868 @@ -274,6 +280,7 @@ void CacheItem::Impl::imageConverted(bool success)
869         file_to_load_ = converter_ ? FileName(converter_->convertedFile())
870                                        : FileName();
871         converter_.reset();
872 +       cc_.disconnect();
873  
874         success = !file_to_load_.empty() && file_to_load_.isReadableFile();
875  
876 @@ -442,13 +449,9 @@ void CacheItem::Impl::convertToDisplayFormat()
877         // Connect a signal to this->imageConverted and pass this signal to
878         // the graphics converter so that we can load the modified file
879         // on completion of the conversion process.
880 -       converter_ = make_unique<Converter>(doc_file_, filename,
881 -                                           to_file_base.absFileName(),
882 +       converter_ = make_unique<Converter>(doc_file_, filename, to_file_base.absFileName(),
883                                             from, to_);
884 -       // Connection is closed at the same time as *this is destroyed.
885 -       converter_->connect([this](bool success){
886 -                       imageConverted(success);
887 -               });
888 +       converter_->connect(bind(&Impl::imageConverted, this, _1));
889         converter_->startConversion();
890  }
891  
892 diff --git a/src/graphics/GraphicsCacheItem.h b/src/graphics/GraphicsCacheItem.h
893 index 6f7f968..9cee2b8 100644
894 --- a/src/graphics/GraphicsCacheItem.h
895 +++ b/src/graphics/GraphicsCacheItem.h
896 @@ -30,7 +30,7 @@
897  
898  #include "GraphicsTypes.h"
899  
900 -#include "support/signals.h"
901 +#include <boost/signals2.hpp>
902  
903  
904  namespace lyx {
905 @@ -82,9 +82,9 @@ public:
906         /** Connect and you'll be informed when the loading status of the image
907          *  changes.
908          */
909 -       typedef signals2::signal<void()>::slot_type slot_type;
910 +       typedef boost::signals2::signal<void()>::slot_type slot_type;
911         ///
912 -       signals2::connection connect(slot_type const &) const;
913 +       boost::signals2::connection connect(slot_type const &) const;
914  
915  private:
916         /// noncopyable
917 diff --git a/src/graphics/GraphicsConverter.cpp b/src/graphics/GraphicsConverter.cpp
918 index 598e108..63b6a44 100644
919 --- a/src/graphics/GraphicsConverter.cpp
920 +++ b/src/graphics/GraphicsConverter.cpp
921 @@ -27,6 +27,7 @@
922  #include "support/lstrings.h"
923  #include "support/os.h"
924  
925 +#include "support/bind.h"
926  #include "support/TempFile.h"
927  
928  #include <sstream>
929 @@ -39,12 +40,10 @@ namespace lyx {
930  
931  namespace graphics {
932  
933 -class Converter::Impl {
934 +class Converter::Impl : public boost::signals2::trackable {
935  public:
936         ///
937 -       Impl(FileName const & doc_fname,
938 -            FileName const & from_file, string const & to_file_base,
939 -            string const & from_format, string const & to_format);
940 +       Impl(FileName const &, FileName const &, string const &, string const &, string const &);
941  
942         ///
943         void startConversion();
944 @@ -59,9 +58,9 @@ public:
945         /** At the end of the conversion process inform the outside world
946          *  by emitting a signal.
947          */
948 -       typedef signals2::signal<void(bool)> sig;
949 +       typedef boost::signals2::signal<void(bool)> SignalType;
950         ///
951 -       sig finishedConversion;
952 +       SignalType finishedConversion;
953  
954         ///
955         FileName const doc_fname_;
956 @@ -75,8 +74,6 @@ public:
957         bool valid_process_;
958         ///
959         bool finished_;
960 -       ///
961 -       Trackable tracker_;
962  };
963  
964  
965 @@ -88,8 +85,8 @@ bool Converter::isReachable(string const & from_format_name,
966  
967  
968  Converter::Converter(FileName const & doc_fname,
969 -                     FileName const & from_file, string const & to_file_base,
970 -                     string const & from_format, string const & to_format)
971 +                    FileName const & from_file, string const & to_file_base,
972 +                    string const & from_format, string const & to_format)
973         : pimpl_(new Impl(doc_fname, from_file, to_file_base, from_format, to_format))
974  {}
975  
976 @@ -106,7 +103,7 @@ void Converter::startConversion() const
977  }
978  
979  
980 -signals2::connection Converter::connect(slot_type const & slot) const
981 +boost::signals2::connection Converter::connect(slot_type const & slot) const
982  {
983         return pimpl_->finishedConversion.connect(slot);
984  }
985 @@ -191,10 +188,9 @@ void Converter::Impl::startConversion()
986                 return;
987         }
988  
989 -       ForkedCall::sigPtr ptr = ForkedCallQueue::add(script_command_);
990 -       ptr->connect(ForkedCall::slot([this](pid_t pid, int retval){
991 -                               converted(pid, retval);
992 -                       }).track_foreign(tracker_.p()));
993 +       ForkedCall::SignalTypePtr ptr =
994 +               ForkedCallQueue::add(script_command_);
995 +       ptr->connect(bind(&Impl::converted, this, _1, _2));
996  }
997  
998  
999 diff --git a/src/graphics/GraphicsConverter.h b/src/graphics/GraphicsConverter.h
1000 index c038029..d3d0b81 100644
1001 --- a/src/graphics/GraphicsConverter.h
1002 +++ b/src/graphics/GraphicsConverter.h
1003 @@ -17,8 +17,7 @@
1004  #ifndef GRAPHICSCONVERTER_H
1005  #define GRAPHICSCONVERTER_H
1006  
1007 -#include "support/signals.h"
1008 -
1009 +#include <boost/signals2.hpp>
1010  
1011  namespace lyx {
1012  
1013 @@ -48,12 +47,11 @@ public:
1014         /** Connect and you'll be informed when the conversion process has
1015          *  finished.
1016          *  If the conversion is successful, then the listener is passed \c true.
1017 -        *  The connection is closed when this is destroyed.
1018          */
1019 -       typedef signals2::signal<void(bool)> sig_type;
1020 +       typedef boost::signals2::signal<void(bool)> sig_type;
1021         typedef sig_type::slot_type slot_type;
1022         ///
1023 -       signals2::connection connect(slot_type const &) const;
1024 +       boost::signals2::connection connect(slot_type const &) const;
1025  
1026         /** If the conversion is successful, this returns the name of the
1027          *  resulting file.
1028 diff --git a/src/graphics/GraphicsLoader.cpp b/src/graphics/GraphicsLoader.cpp
1029 index 683f092..3503aba 100644
1030 --- a/src/graphics/GraphicsLoader.cpp
1031 +++ b/src/graphics/GraphicsLoader.cpp
1032 @@ -107,17 +107,16 @@ void LoaderQueue::loadNext()
1033  
1034  
1035  LoaderQueue::LoaderQueue() : timer(s_millisecs_, Timeout::ONETIME),
1036 -                             running_(false)
1037 +                            running_(false)
1038  {
1039 -       // Disconnected when this is destroyed
1040 -       timer.timeout.connect([this](){ loadNext(); });
1041 +       timer.timeout.connect(bind(&LoaderQueue::loadNext, this));
1042  }
1043  
1044  
1045  void LoaderQueue::startLoader()
1046  {
1047         LYXERR(Debug::GRAPHICS, "LoaderQueue: waking up");
1048 -       running_ = true;
1049 +       running_ = true ;
1050         timer.setTimeout(s_millisecs_);
1051         timer.start();
1052  }
1053 @@ -164,7 +163,7 @@ void LoaderQueue::touch(Cache::ItemPtr const & item)
1054  
1055  typedef std::shared_ptr<Image> ImagePtr;
1056  
1057 -class Loader::Impl {
1058 +class Loader::Impl : public boost::signals2::trackable {
1059         friend class Loader;
1060  public:
1061         ///
1062 @@ -193,9 +192,9 @@ public:
1063         /// We modify a local copy of the image once it is loaded.
1064         ImagePtr image_;
1065         /// This signal is emitted when the image loading status changes.
1066 -       signals2::signal<void()> signal_;
1067 -       /// The connection of the signal statusChanged
1068 -       signals2::scoped_connection connection_;
1069 +       boost::signals2::signal<void()> signal_;
1070 +       /// The connection of the signal StatusChanged  
1071 +       boost::signals2::connection sc_;
1072  
1073         double displayPixelRatio() const
1074         {
1075 @@ -364,7 +363,7 @@ void Loader::setDisplayPixelRatio(double scale)
1076  }
1077  
1078  
1079 -signals2::connection Loader::connect(slot const & slot) const
1080 +boost::signals2::connection Loader::connect(slot_type const & slot) const
1081  {
1082         return pimpl_->signal_.connect(slot);
1083  }
1084 @@ -406,7 +405,7 @@ void Loader::Impl::resetFile(FileName const & file)
1085                 // signal needs to be disconnected.
1086                 try {
1087                         // This can in theory throw a BufferException
1088 -                       connection_.disconnect();
1089 +                       sc_.disconnect();
1090                 } catch (...) {
1091                         LYXERR(Debug::GRAPHICS, "Unable to disconnect signal.");
1092                 }
1093 @@ -435,8 +434,7 @@ void Loader::Impl::resetFile(FileName const & file)
1094         if (continue_monitoring && !cached_item_->monitoring())
1095                 cached_item_->startMonitoring();
1096  
1097 -       // This is a scoped connection
1098 -       connection_ = cached_item_->connect([this](){ statusChanged(); });
1099 +       sc_ = cached_item_->connect(bind(&Impl::statusChanged, this));
1100  }
1101  
1102  
1103 diff --git a/src/graphics/GraphicsLoader.h b/src/graphics/GraphicsLoader.h
1104 index 0a299cb..62ea303 100644
1105 --- a/src/graphics/GraphicsLoader.h
1106 +++ b/src/graphics/GraphicsLoader.h
1107 @@ -26,7 +26,7 @@
1108  
1109  #include "GraphicsTypes.h"
1110  
1111 -#include "support/signals.h"
1112 +#include <boost/signals2.hpp>
1113  
1114  namespace lyx {
1115  
1116 @@ -70,7 +70,7 @@ public:
1117          */
1118         void startLoading() const;
1119  
1120 -       /** Tries to reload the image.
1121 +       /** Tries to reload the image. 
1122          */
1123         void reload() const;
1124  
1125 @@ -90,10 +90,10 @@ public:
1126         /** Connect and you'll be informed when the loading status of the image
1127          *  changes.
1128          */
1129 -       typedef signals2::signal<void()> sig;
1130 -       typedef sig::slot_type slot;
1131 +       typedef boost::signals2::signal<void()> sig_type;
1132 +       typedef sig_type::slot_type slot_type;
1133         ///
1134 -       signals2::connection connect(slot const &) const;
1135 +       boost::signals2::connection connect(slot_type const &) const;
1136  
1137         /** The loaded image with Pixmap set.
1138          *  If the Pixmap is not yet set (see status() for why...), returns 0.
1139 diff --git a/src/graphics/PreviewImage.cpp b/src/graphics/PreviewImage.cpp
1140 index b80bf94..da0f1e2 100644
1141 --- a/src/graphics/PreviewImage.cpp
1142 +++ b/src/graphics/PreviewImage.cpp
1143 @@ -20,6 +20,7 @@
1144  
1145  #include "support/FileName.h"
1146  
1147 +#include "support/bind.h"
1148  
1149  using namespace std;
1150  using namespace lyx::support;
1151 @@ -27,7 +28,7 @@ using namespace lyx::support;
1152  namespace lyx {
1153  namespace graphics {
1154  
1155 -class PreviewImage::Impl {
1156 +class PreviewImage::Impl : public boost::signals2::trackable {
1157  public:
1158         ///
1159         Impl(PreviewImage & p, PreviewLoader & l,
1160 @@ -104,14 +105,15 @@ PreviewLoader & PreviewImage::previewLoader() const
1161  }
1162  
1163  
1164 -PreviewImage::Impl::Impl(PreviewImage & p, PreviewLoader & l, string const & s,
1165 -                         FileName const & bf, double af)
1166 +PreviewImage::Impl::Impl(PreviewImage & p, PreviewLoader & l,
1167 +                        string const & s,
1168 +                        FileName const & bf,
1169 +                        double af)
1170         : parent_(p), ploader_(l), iloader_(l.buffer().fileName(), bf),
1171           snippet_(s), ascent_frac_(af)
1172  {
1173         iloader_.setDisplayPixelRatio(l.displayPixelRatio());
1174 -       // This connection is destroyed at the same time as this.
1175 -       iloader_.connect([this](){ statusChanged(); });
1176 +       iloader_.connect(bind(&Impl::statusChanged, this));
1177  }
1178  
1179  
1180 diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp
1181 index 22b0f23..c6f4d06 100644
1182 --- a/src/graphics/PreviewLoader.cpp
1183 +++ b/src/graphics/PreviewLoader.cpp
1184 @@ -38,6 +38,7 @@
1185  #include "support/ForkedCalls.h"
1186  #include "support/lstrings.h"
1187  
1188 +#include "support/bind.h"
1189  #include "support/TempFile.h"
1190  
1191  #include <atomic>
1192 @@ -166,7 +167,7 @@ typedef InProgressProcesses::value_type InProgressProcess;
1193  namespace lyx {
1194  namespace graphics {
1195  
1196 -class PreviewLoader::Impl {
1197 +class PreviewLoader::Impl : public boost::signals2::trackable {
1198  public:
1199         ///
1200         Impl(PreviewLoader & p, Buffer const & b);
1201 @@ -187,7 +188,7 @@ public:
1202         void refreshPreviews();
1203  
1204         /// Emit this signal when an image is ready for display.
1205 -       signals2::signal<void(PreviewImage const &)> imageReady;
1206 +       boost::signals2::signal<void(PreviewImage const &)> imageReady;
1207  
1208         Buffer const & buffer() const { return buffer_; }
1209  
1210 @@ -238,8 +239,6 @@ private:
1211  
1212         /// We don't own this
1213         static lyx::Converter const * pconverter_;
1214 -
1215 -       signals2::scoped_connection connection_;
1216  };
1217  
1218  
1219 @@ -297,7 +296,7 @@ void PreviewLoader::refreshPreviews()
1220  }
1221  
1222  
1223 -signals2::connection PreviewLoader::connect(slot const & slot) const
1224 +boost::signals2::connection PreviewLoader::connect(slot_type const & slot) const
1225  {
1226         return pimpl_->imageReady.connect(slot);
1227  }
1228 @@ -708,12 +707,12 @@ void PreviewLoader::Impl::startLoading(bool wait)
1229            << " " << quoteName(latexfile.toFilesystemEncoding())
1230            << " --dpi " << font_scaling_factor_;
1231  
1232 -       // FIXME XHTML
1233 +       // FIXME XHTML 
1234         // The colors should be customizable.
1235         if (!buffer_.isExporting()) {
1236                 ColorCode const fg = PreviewLoader::foregroundColor();
1237                 ColorCode const bg = PreviewLoader::backgroundColor();
1238 -               cs << " --fg " << theApp()->hexName(fg)
1239 +               cs << " --fg " << theApp()->hexName(fg) 
1240                    << " --bg " << theApp()->hexName(bg);
1241         }
1242  
1243 @@ -737,11 +736,9 @@ void PreviewLoader::Impl::startLoading(bool wait)
1244         }
1245  
1246         // Initiate the conversion from LaTeX to bitmap images files.
1247 -       ForkedCall::sigPtr convert_ptr = make_shared<ForkedCall::sig>();
1248 -       // This is a scoped connection
1249 -       connection_ = convert_ptr->connect([this](pid_t pid, int retval){
1250 -                       finishedGenerating(pid, retval);
1251 -               });
1252 +       ForkedCall::SignalTypePtr
1253 +               convert_ptr(new ForkedCall::SignalType);
1254 +       convert_ptr->connect(bind(&Impl::finishedGenerating, this, _1, _2));
1255  
1256         ForkedCall call(buffer_.filePath());
1257         int ret = call.startScript(command, convert_ptr);
1258 diff --git a/src/graphics/PreviewLoader.h b/src/graphics/PreviewLoader.h
1259 index ca22a9f..3239ffc 100644
1260 --- a/src/graphics/PreviewLoader.h
1261 +++ b/src/graphics/PreviewLoader.h
1262 @@ -18,8 +18,7 @@
1263  #ifndef PREVIEWLOADER_H
1264  #define PREVIEWLOADER_H
1265  
1266 -#include "support/signals.h"
1267 -
1268 +#include <boost/signals2.hpp>
1269  #include <QObject>
1270  
1271  #include "ColorCode.h"
1272 @@ -77,10 +76,10 @@ public:
1273          *  has been created and is ready for loading through
1274          *  lyx::graphics::PreviewImage::image().
1275          */
1276 -       typedef signals2::signal<void(PreviewImage const &)> sig;
1277 -       typedef sig::slot_type slot;
1278 +       typedef boost::signals2::signal<void(PreviewImage const &)> sig_type;
1279 +       typedef sig_type::slot_type slot_type;
1280         ///
1281 -       signals2::connection connect(slot const &) const;
1282 +       boost::signals2::connection connect(slot_type const &) const;
1283  
1284         /** When PreviewImage has finished loading the image file into memory,
1285          *  it tells the PreviewLoader to tell the outside world
1286 diff --git a/src/insets/InsetExternal.cpp b/src/insets/InsetExternal.cpp
1287 index 1f0f5f2..e1130bf 100644
1288 --- a/src/insets/InsetExternal.cpp
1289 +++ b/src/insets/InsetExternal.cpp
1290 @@ -39,6 +39,7 @@
1291  
1292  #include "graphics/PreviewLoader.h"
1293  
1294 +#include "support/bind.h"
1295  #include "support/convert.h"
1296  #include "support/debug.h"
1297  #include "support/ExceptionMessage.h"
1298 @@ -426,6 +427,7 @@ InsetExternal::InsetExternal(Buffer * buf)
1299  // Mouse hover is not copied and remains empty
1300  InsetExternal::InsetExternal(InsetExternal const & other)
1301         : Inset(other),
1302 +         boost::signals2::trackable(),
1303           params_(other.params_),
1304           renderer_(other.renderer_->clone(this))
1305  {}
1306 @@ -652,7 +654,6 @@ void InsetExternal::updatePreview() const
1307         case PREVIEW_INSTANT: {
1308                 renderer_ = make_unique<RenderMonitoredPreview>(this);
1309                 RenderMonitoredPreview * preview_ptr = renderer_->asMonitoredPreview();
1310 -               // This connection is closed at the same time as this is destroyed.
1311                 preview_ptr->connect([=]() { fileChanged(); });
1312                 add_preview_and_start_loading(*preview_ptr, *this, buffer());
1313                 break;
1314 diff --git a/src/insets/InsetExternal.h b/src/insets/InsetExternal.h
1315 index 75b7f70..4a15be1 100644
1316 --- a/src/insets/InsetExternal.h
1317 +++ b/src/insets/InsetExternal.h
1318 @@ -19,6 +19,8 @@
1319  #include "support/FileName.h"
1320  #include "support/unique_ptr.h"
1321  
1322 +#include <boost/signals2/trackable.hpp>
1323 +
1324  
1325  namespace lyx {
1326  
1327 @@ -88,7 +90,7 @@ private:
1328  class RenderBase;
1329  
1330  ///
1331 -class InsetExternal : public Inset
1332 +class InsetExternal : public Inset, public boost::signals2::trackable
1333  {
1334         // Disable assignment operator, since it is not used, and it is too
1335         // complicated to implement it consistently with the copy constructor
1336 diff --git a/src/insets/RenderPreview.cpp b/src/insets/RenderPreview.cpp
1337 index 18882fc..948ddb9 100644
1338 --- a/src/insets/RenderPreview.cpp
1339 +++ b/src/insets/RenderPreview.cpp
1340 @@ -31,6 +31,8 @@
1341  #include "support/lassert.h"
1342  #include "support/lstrings.h"
1343  
1344 +#include "support/bind.h"
1345 +
1346  using namespace std;
1347  using namespace lyx::support;
1348  
1349 @@ -75,11 +77,19 @@ RenderPreview::RenderPreview(Inset const * inset)
1350  RenderPreview::RenderPreview(RenderPreview const & other,
1351                              Inset const * inset)
1352         : RenderBase(other),
1353 +         boost::signals2::trackable(),
1354           snippet_(other.snippet_),
1355           parent_(inset)
1356  {}
1357  
1358  
1359 +RenderPreview::~RenderPreview()
1360 +{
1361 +       if (ploader_connection_.connected())
1362 +               ploader_connection_.disconnect();
1363 +}
1364 +
1365 +
1366  RenderBase * RenderPreview::clone(Inset const * inset) const
1367  {
1368         return new RenderPreview(*this, inset);
1369 @@ -231,12 +241,10 @@ void RenderPreview::addPreview(docstring const & latex_snippet,
1370         // If this is the first time of calling, connect to the
1371         // PreviewLoader signal that'll inform us when the preview image
1372         // is ready for loading.
1373 -       if (!ploader_connection_.connected())
1374 -               // This is a scoped connection.
1375 -               ploader_connection_ =
1376 -                       ploader.connect([this](graphics::PreviewImage const & pi){
1377 -                               imageReady(pi);
1378 -                       });
1379 +       if (!ploader_connection_.connected()) {
1380 +               ploader_connection_ = ploader.connect(
1381 +                       bind(&RenderPreview::imageReady, this, _1));
1382 +       }
1383  
1384         ploader.add(snippet_);
1385  }
1386 @@ -288,7 +296,8 @@ void RenderMonitoredPreview::draw(PainterInfo & pi, int x, int y) const
1387  }
1388  
1389  
1390 -signals2::connection RenderMonitoredPreview::connect(slot const & slot)
1391 +boost::signals2::connection
1392 +RenderMonitoredPreview::connect(ChangedSig::slot_type const & slot)
1393  {
1394         return changed_.connect(slot);
1395  }
1396 diff --git a/src/insets/RenderPreview.h b/src/insets/RenderPreview.h
1397 index 2f83aff..42d944d 100644
1398 --- a/src/insets/RenderPreview.h
1399 +++ b/src/insets/RenderPreview.h
1400 @@ -21,8 +21,10 @@
1401  #include "support/docstring.h"
1402  #include "support/FileMonitor.h"
1403  #include "support/FileName.h"
1404 -#include "support/signals.h"
1405  
1406 +#include <boost/signals2.hpp>
1407 +#include <boost/signals2/trackable.hpp>
1408 +#include <boost/signals2/connection.hpp>
1409  
1410  namespace lyx {
1411  
1412 @@ -38,7 +40,7 @@ class PreviewLoader;
1413  } // namespace graphics
1414  
1415  
1416 -class RenderPreview : public RenderBase {
1417 +class RenderPreview : public RenderBase, public boost::signals2::trackable {
1418  public:
1419         /// Return true if preview is enabled in text (from LyXRC::preview)
1420         static bool previewText();
1421 @@ -47,6 +49,7 @@ public:
1422  
1423         RenderPreview(Inset const *);
1424         RenderPreview(RenderPreview const &, Inset const *);
1425 +       ~RenderPreview();
1426         RenderBase * clone(Inset const *) const;
1427  
1428         /// Compute the size of the object, returned in dim
1429 @@ -101,7 +104,7 @@ private:
1430         /** Store the connection to the preview loader so that we connect
1431          *  only once.
1432          */
1433 -       signals2::scoped_connection ploader_connection_;
1434 +       boost::signals2::connection ploader_connection_;
1435  
1436         /// Inform the core that the inset has changed.
1437         Inset const * parent_;
1438 @@ -121,17 +124,15 @@ public:
1439         void stopMonitoring() const;
1440  
1441         /// Connect and you'll be informed when the file changes.
1442 -       /// Do not forget to track objects used by the slot.
1443 -       typedef signals2::signal<void()> sig;
1444 -       typedef sig::slot_type slot;
1445 -       signals2::connection connect(slot const & slot);
1446 +       typedef boost::signals2::signal<void()> ChangedSig;
1447 +       boost::signals2::connection connect(ChangedSig::slot_type const &);
1448  
1449         /// equivalent to dynamic_cast
1450         virtual RenderMonitoredPreview * asMonitoredPreview() { return this; }
1451  
1452  private:
1453         /// This signal is emitted if the file is modified
1454 -       sig changed_;
1455 +       ChangedSig changed_;
1456         ///
1457         mutable support::ActiveFileMonitorPtr monitor_;
1458         ///
1459 diff --git a/src/support/FileMonitor.cpp b/src/support/FileMonitor.cpp
1460 index f1fefb8..30a4170 100644
1461 --- a/src/support/FileMonitor.cpp
1462 +++ b/src/support/FileMonitor.cpp
1463 @@ -176,7 +176,8 @@ void FileMonitor::reconnectToFileMonitorGuard()
1464  }
1465  
1466  
1467 -signals2::connection FileMonitor::connect(slot const & slot)
1468 +boost::signals2::connection
1469 +FileMonitor::connect(sig::slot_type const & slot)
1470  {
1471         return fileChanged_.connect(slot);
1472  }
1473 diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h
1474 index 49f12cb..23302ed 100644
1475 --- a/src/support/FileMonitor.h
1476 +++ b/src/support/FileMonitor.h
1477 @@ -17,7 +17,6 @@
1478  #define FILEMONITOR_H
1479  
1480  #include "support/FileName.h"
1481 -#include "support/signals.h"
1482  
1483  #include <memory>
1484  
1485 @@ -25,6 +24,8 @@
1486  #include <QObject>
1487  #include <QPointer>
1488  
1489 +#include <boost/signals2.hpp>
1490 +
1491  
1492  namespace lyx {
1493  namespace support {
1494 @@ -157,10 +158,9 @@ class FileMonitor : public QObject
1495  public:
1496         FileMonitor(std::shared_ptr<FileMonitorGuard> monitor);
1497  
1498 -       typedef signals2::signal<void()> sig;
1499 -       typedef sig::slot_type slot;
1500 +       typedef boost::signals2::signal<void()> sig;
1501         /// Connect and you'll be informed when the file has changed.
1502 -       signals2::connection connect(slot const &);
1503 +       boost::signals2::connection connect(sig::slot_type const &);
1504         /// disconnect all slots connected to the boost signal fileChanged_ or to
1505         /// the qt signal fileChanged()
1506         void disconnect();
1507 diff --git a/src/support/ForkedCalls.cpp b/src/support/ForkedCalls.cpp
1508 index f81c1d2..93be6a4 100644
1509 --- a/src/support/ForkedCalls.cpp
1510 +++ b/src/support/ForkedCalls.cpp
1511 @@ -58,7 +58,7 @@ namespace {
1512  //
1513  /////////////////////////////////////////////////////////////////////
1514  
1515 -class Murder {
1516 +class Murder : public boost::signals2::trackable {
1517  public:
1518         //
1519         static void killItDead(int secs, pid_t pid)
1520 @@ -83,8 +83,7 @@ private:
1521         Murder(int secs, pid_t pid)
1522                 : timeout_(1000*secs, Timeout::ONETIME), pid_(pid)
1523         {
1524 -               // Connection is closed with this.
1525 -               timeout_.timeout.connect([this](){ kill(); });
1526 +               timeout_.timeout.connect(lyx::bind(&Murder::kill, this));
1527                 timeout_.start();
1528         }
1529  
1530 @@ -278,7 +277,7 @@ ForkedCall::ForkedCall(string const & path, string const & lpath)
1531  int ForkedCall::startScript(Starttype wait, string const & what)
1532  {
1533         if (wait != Wait) {
1534 -               retval_ = startScript(what, sigPtr());
1535 +               retval_ = startScript(what, SignalTypePtr());
1536                 return retval_;
1537         }
1538  
1539 @@ -288,7 +287,7 @@ int ForkedCall::startScript(Starttype wait, string const & what)
1540  }
1541  
1542  
1543 -int ForkedCall::startScript(string const & what, sigPtr signal)
1544 +int ForkedCall::startScript(string const & what, SignalTypePtr signal)
1545  {
1546         command_ = commandPrep(trim(what));
1547         signal_  = signal;
1548 @@ -436,13 +435,13 @@ int ForkedCall::generateChild()
1549  namespace ForkedCallQueue {
1550  
1551  /// A process in the queue
1552 -typedef pair<string, ForkedCall::sigPtr> Process;
1553 +typedef pair<string, ForkedCall::SignalTypePtr> Process;
1554  /** Add a process to the queue. Processes are forked sequentially
1555   *  only one is running at a time.
1556   *  Connect to the returned signal and you'll be informed when
1557   *  the process has ended.
1558   */
1559 -ForkedCall::sigPtr add(string const & process);
1560 +ForkedCall::SignalTypePtr add(string const & process);
1561  
1562  /// in-progress queue
1563  static queue<Process> callQueue_;
1564 @@ -457,10 +456,10 @@ void stopCaller();
1565  ///
1566  void callback(pid_t, int);
1567  
1568 -ForkedCall::sigPtr add(string const & process)
1569 +ForkedCall::SignalTypePtr add(string const & process)
1570  {
1571 -       ForkedCall::sigPtr ptr;
1572 -       ptr.reset(new ForkedCall::sig);
1573 +       ForkedCall::SignalTypePtr ptr;
1574 +       ptr.reset(new ForkedCall::SignalType);
1575         callQueue_.push(Process(process, ptr));
1576         if (!running_)
1577                 startCaller();
1578 diff --git a/src/support/ForkedCalls.h b/src/support/ForkedCalls.h
1579 index 8a4bf1d..eececc0 100644
1580 --- a/src/support/ForkedCalls.h
1581 +++ b/src/support/ForkedCalls.h
1582 @@ -14,8 +14,8 @@
1583  #ifndef FORKEDCALLS_H
1584  #define FORKEDCALLS_H
1585  
1586 -#include "support/signals.h"
1587  #include "support/strfwd.h"
1588 +#include <boost/signals2.hpp>
1589  
1590  #ifdef HAVE_SYS_TYPES_H
1591  # include <sys/types.h>
1592 @@ -44,7 +44,7 @@ public:
1593         ///
1594         virtual std::shared_ptr<ForkedProcess> clone() const = 0;
1595  
1596 -       /** A Signal signal can be emitted once the forked process
1597 +       /** A SignalType signal can be emitted once the forked process
1598          *  has finished. It passes:
1599          *  the PID of the child and;
1600          *  the return value from the child.
1601 @@ -53,8 +53,7 @@ public:
1602          *  we can return easily to C++ methods, rather than just globally
1603          *  accessible functions.
1604          */
1605 -       typedef signals2::signal<void(pid_t, int)> sig;
1606 -       typedef sig::slot_type slot;
1607 +       typedef boost::signals2::signal<void(pid_t, int)> SignalType;
1608  
1609         /** The signal is connected in the calling routine to the desired
1610          *  slot. We pass a shared_ptr rather than a reference to the signal
1611 @@ -62,10 +61,9 @@ public:
1612          *  class (and hence the signal) to be destructed before the forked
1613          *  call is complete.
1614          *
1615 -        *  Use Slot::track or Signal::scoped_connection to ensure that the
1616 -        *  connection is closed before the slot expires.
1617 +        *  It doesn't matter if the slot disappears, SigC takes care of that.
1618          */
1619 -       typedef std::shared_ptr<sig> sigPtr;
1620 +       typedef std::shared_ptr<SignalType> SignalTypePtr;
1621  
1622         /** Invoking the following methods makes sense only if the command
1623          *  is running asynchronously!
1624 @@ -116,7 +114,7 @@ protected:
1625         pid_t fork();
1626  
1627         /// Callback function
1628 -       sigPtr signal_;
1629 +       SignalTypePtr signal_;
1630  
1631         /// identifying command (for display in the GUI perhaps).
1632         std::string command_;
1633 @@ -138,7 +136,7 @@ private:
1634  };
1635  
1636  
1637 -/**
1638 +/** 
1639   * An instance of class ForkedCall represents a single child process.
1640   *
1641   * Class ForkedCall uses fork() and execvp() to lauch the child process.
1642 @@ -177,7 +175,7 @@ public:
1643         int startScript(Starttype, std::string const & what);
1644  
1645         ///
1646 -       int startScript(std::string const & what, sigPtr ptr);
1647 +       int startScript(std::string const & what, SignalTypePtr);
1648  
1649  private:
1650         ///
1651 @@ -197,7 +195,7 @@ private:
1652  
1653  namespace ForkedCallQueue {
1654  
1655 -ForkedCall::sigPtr add(std::string const & process);
1656 +ForkedCall::SignalTypePtr add(std::string const & process);
1657  /// Query whether the queue is running a forked process now.
1658  bool running();
1659  
1660 diff --git a/src/support/Makefile.am b/src/support/Makefile.am
1661 index d3c902c..9865d6f 100644
1662 --- a/src/support/Makefile.am
1663 +++ b/src/support/Makefile.am
1664 @@ -93,7 +93,6 @@ liblyxsupport_a_SOURCES = \
1665         qstring_helpers.h \
1666         regex.h \
1667         RefChanger.h \
1668 -       signals.h \
1669         socktools.cpp \
1670         socktools.h \
1671         strfwd.h \
1672 diff --git a/src/support/Timeout.h b/src/support/Timeout.h
1673 index eef78db..042ed45 100644
1674 --- a/src/support/Timeout.h
1675 +++ b/src/support/Timeout.h
1676 @@ -12,7 +12,7 @@
1677  #ifndef TIMEOUT_H
1678  #define TIMEOUT_H
1679  
1680 -#include "support/signals.h"
1681 +#include <boost/signals2.hpp>
1682  
1683  
1684  namespace lyx {
1685 @@ -40,7 +40,7 @@ public:
1686         /// restart the timer
1687         void restart();
1688         /// signal emitted on timer expiry
1689 -       signals2::signal<void()> timeout;
1690 +       boost::signals2::signal<void()> timeout;
1691         /// emit the signal
1692         void emit();
1693         /// set the timer type
1694 diff --git a/src/support/signals.h b/src/support/signals.h
1695 deleted file mode 100644
1696 index 7d4d116..0000000
1697 --- a/src/support/signals.h
1698 +++ /dev/null
1699 @@ -1,49 +0,0 @@
1700 -// -*- C++ -*-
1701 -/**
1702 - * \file signals.h
1703 - * This file is part of LyX, the document processor.
1704 - * Licence details can be found in the file COPYING.
1705 - *
1706 - * \author Guillaume Munch
1707 - *
1708 - * Full author contact details are available in file CREDITS.
1709 - */
1710 -
1711 -#ifndef LYX_SIGNALS_H
1712 -#define LYX_SIGNALS_H
1713 -
1714 -#include "boost/signals2.hpp"
1715 -
1716 -#include <memory>
1717 -
1718 -namespace lyx {
1719 -
1720 -namespace signals2 = ::boost::signals2;
1721 -
1722 -namespace support {
1723 -
1724 -/// A small utility to use with signals2::slot_type::track_foreign when the
1725 -/// parent object is not handled by a shared_ptr, or to track the lifetime of an
1726 -/// object. Using Trackable to track lifetimes is less thread-safe than tracking
1727 -/// their parents directly with a shared_ptr as recommended by signals2, but it
1728 -/// makes it easier for transitioning old code. (Essentially because Trackable
1729 -/// will not prevent the deletion of the parent by a concurrent thread.)
1730 -class Trackable {
1731 -public:
1732 -       Trackable() : p_(std::make_shared<int>(0)) {}
1733 -       Trackable(Trackable const &) : Trackable() {}
1734 -       Trackable(Trackable &&) : Trackable() {}
1735 -       Trackable & operator=(Trackable const &) { return *this; }
1736 -       Trackable & operator=(Trackable &&) { return *this; }
1737 -       // This weak pointer lets you know if the parent object has been destroyed
1738 -       std::weak_ptr<void> p() const { return p_; }
1739 -private:
1740 -       std::shared_ptr<void> const p_;
1741 -};
1742 -
1743 -} // namespace support
1744 -
1745 -} // namespace lyx
1746 -
1747 -
1748 -#endif
1749
1750 commit c6b1ee490c9467230ba7033bd15feb4753832c4b
1751 Author: Pavel Sanda <psanda@ucsd.edu>
1752 Date:   Thu Nov 16 09:38:27 2017 -0800
1753
1754     one forgotten line in rejects
1755
1756 diff --git a/src/Buffer.cpp b/src/Buffer.cpp
1757 index 48391f9..1945b71 100644
1758 --- a/src/Buffer.cpp
1759 +++ b/src/Buffer.cpp
1760 @@ -5349,7 +5349,7 @@ void Buffer::Impl::refreshFileMonitor()
1761  }
1762  
1763  
1764 -void Buffer::Impl::fileExternallyModified(bool const exists)
1765 +void Buffer::Impl::fileExternallyModified(bool modified)
1766  {
1767         if (modified) 
1768                 lyx_clean = bak_clean = false;