diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 8da66183a..a2358a3b5 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -249,20 +249,13 @@ void BatchQueuePanel::queueSizeChanged(int qsize, bool queueRunning, bool queueE { updateTab (qsize); - if (qsize == 0 || (qsize == 1 && queueRunning)) { - qStartStop->set_sensitive(false); - } else { - qStartStop->set_sensitive(true); - } + setGuiFromBatchState(queueRunning, qsize); - if (!queueRunning) { - stopBatchProc (); - fdir->set_sensitive (true); - fformat->set_sensitive (true); + if (!queueRunning && qsize == 0 && queueShouldRun) { + // There was work, but it is all done now. + queueShouldRun = false; - if (qsize == 0) { - SoundManager::playSoundAsync(options.sndBatchQueueDone); - } + SoundManager::playSoundAsync(options.sndBatchQueueDone); } if (queueError) { @@ -273,8 +266,7 @@ void BatchQueuePanel::queueSizeChanged(int qsize, bool queueRunning, bool queueE void BatchQueuePanel::startOrStopBatchProc() { - bool state = qStartStop->get_state(); - if (state) { + if (qStartStop->get_state()) { startBatchProc(); } else { stopBatchProc(); @@ -283,22 +275,17 @@ void BatchQueuePanel::startOrStopBatchProc() void BatchQueuePanel::startBatchProc () { - // Update switch when queue started programmatically - qStartStopConn.block (true); - qStartStop->set_active(true); - qStartStopState = true; - qStartStopConn.block (false); - if (batchQueue->hasJobs()) { - fdir->set_sensitive (false); - fformat->set_sensitive (false); - if (batchQueue->getEntries().size() == 1) { - qStartStop->set_sensitive(false); - } + // Update the *desired* state of the queue, then launch it. The switch + // state is not updated here; it is changed by the queueSizeChanged() + // callback in response to the *reported* state. + queueShouldRun = true; + + // Don't need an update callback from the queue to know it is started: + setGuiFromBatchState(true, batchQueue->getEntries().size()); + saveOptions(); batchQueue->startProcessing (); - } else { - stopBatchProc (); } updateTab (batchQueue->getEntries().size()); @@ -306,20 +293,37 @@ void BatchQueuePanel::startBatchProc () void BatchQueuePanel::stopBatchProc () { - // Update switch when queue started programmatically - qStartStopConn.block (true); - qStartStop->set_active(false); - qStartStopState = false; - qStartStopConn.block (false); + // There is nothing much to do here except set the desired state, which the + // background queue thread must check. It will notify queueSizeChanged() + // when it stops. + queueShouldRun = false; updateTab (batchQueue->getEntries().size()); } +void BatchQueuePanel::setGuiFromBatchState(bool queueRunning, int qsize) +{ + // Change the GUI state in response to the reported queue state + if (qsize == 0 || (qsize == 1 && queueRunning)) { + qStartStop->set_sensitive(false); + } else { + qStartStop->set_sensitive(true); + } + + qStartStopConn.block(true); + qStartStop->set_active(queueRunning); + qStartStopConn.block(false); + + fdir->set_sensitive (!queueRunning); + fformat->set_sensitive (!queueRunning); +} + void BatchQueuePanel::addBatchQueueJobs(const std::vector& entries, bool head) { batchQueue->addEntries(entries, head); if (!qStartStop->get_active() && qAutoStart->get_active()) { + // Auto-start as if the user had pressed the qStartStop switch startBatchProc (); } } @@ -354,9 +358,9 @@ bool BatchQueuePanel::handleShortcutKey (GdkEventKey* event) bool BatchQueuePanel::canStartNext () { - // This function is called from the background BatchQueue thread. - // It cannot call UI functions, so grab the stored state of qStartStop. - return qStartStopState; + // This function is called from the background BatchQueue thread. It + // cannot call UI functions; we keep the desired state in an atomic. + return queueShouldRun; } void BatchQueuePanel::pathFolderButtonPressed () diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index 74c9750e7..e21e01352 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -53,7 +53,7 @@ class BatchQueuePanel : public Gtk::VBox, Gtk::HBox* bottomBox; Gtk::HBox* topBox; - std::atomic qStartStopState; + std::atomic queueShouldRun; IdleRegister idle_register; @@ -76,6 +76,7 @@ private: void startBatchProc (); void stopBatchProc (); void startOrStopBatchProc(); + void setGuiFromBatchState(bool queueRunning, int qsize); void pathFolderChanged (); void pathFolderButtonPressed ();